🎄

ENCA 10日目: ArrayBuffer の長さの最大値明示

2024/12/10に公開

JavaScript でバイナリデータの取り扱いに関わる歴史

ES5.1 までの言語仕様ではバイナリデータを扱うための共通 API がありませんでした。バイナリデータを扱いたい場合、Web 標準では文字列で代替し[1]、Node.js では独自の Buffer クラス使っていました。

ブラウザ上でインタラクティブな CG を扱う WebGL でバイナリデータを扱う必要性が生じ、ArrayBuffer と各種型付き配列(TypedArray)、そして DataView が Internet Explorer 11 に実装されました。その後 WebGL から ES2015 に仕様が移され今に至ります。

ちなみに TypeScript の型定義ファイルにおいて、言語仕様としては ES2015 からであるにも関わらず ES5 から ArrayBuffer などが定義されているのは、IE11 ターゲットのコードを書く際の利便性のためだと考えられます。

ArrayBuffer の長さの最大値明示

ArrayBuffer の長さの最大値は特に仕様で定められておらず、単にメモリ確保に失敗したら RangeError を投げるとしか定められていませんでした。

2017年の段階で ArrayBuffer の最大値が number の安全な整数値最大である 2^{53} - 1Number.MAX_SAFE_INTEGER)を超えた場合、インデックスの計算が破綻してしまうため理論的におかしくなってしまうと指摘されました。しかし実装側としてはそもそもそこまで大きいメモリ確保は失敗することから誰も困っておらず good first issue のまま長いこと放置されていました。

https://github.com/tc39/ecma262/issues/1032

2023年4月に 2^{53} - 1 を超えた場合は必ず RangeError とする一行を追加する PR が作られ、翌5月の会議で承認されました。

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

その後の V8 の対応

V8 で大きいバイナリデータを扱うことを考慮していなかったからか 2^{32} より大きい ArrayBuffer が作れないようになっていましたが、その制限が取り払われました。

https://chromium.googlesource.com/v8/v8.git/+/44b299590083b888637c79fb5632806e607ab861

脚注
  1. 個人的な思い出となりますが XMLHttpRequest v1 の時代にバイナリデータを何とか文字列として取得するために x-user-defined 文字コードを使ったりInternet Explorer 10 以下で VBScript を使ったりしていたのを覚えています。今となってはいい思い出です。 ↩︎

Discussion