2025-09 の TC39 meeting
まとめ
Agenda: https://github.com/tc39/agendas/blob/main/2025/09.md
速報: https://x.com/robpalmer2/status/1970941550361465158
Note: https://github.com/tc39/notes/tree/main/meetings/2025-09
決まったこと
Web compatibility issues / Needs Consensus PRs
Normative: Add CompactDisplay slot to Intl.PluralRules (slides) | Ben Allen
Intl.PluralRules.prototype.select メソッドに数値を渡すことで、その言語で数がどのカテゴリに属するか取得することができる。
code: js
const pr = new Intl.PluralRules("en");
console.log(pr.select(0)); // "other"
console.log(pr.select(1)); // "one"
console.log(pr.select(2)); // "other"
一部言語で数量の短縮形(例: 1K)と長形(例: 1 thousand)で、複数形として扱うか、単数形として扱うかが異なる場合があり、これを区別したいことがある。
code: js
const standard = new Intl.PluralRules(locale);
const compact = new Intl.PluralRules(locale, { notation: "compact" });
console.log(standard.select(1000) !== compact.select(1000));
現在 CLDR にはこの情報が含まれていないが、とりあえず Intl.PluralRules に [[CompactDisplay]] 内部スロットを追加しておき、将来 CLDR に情報が含まれるようになった際に扱えるようにする Normative Change。承認された。
Normative: Make Intl.PluralRules ResolvePlural and associated AOs take Intl mathematical values rather than Numbers (slides) | Ben Allen
Intl.PluralRules.prototype.select メソッドが現状 bigint を入力すると TypeError を投げるようになっているが、それを受け取れるようにする Normative Change。 承認された。
Normative: change PromiseResolve species check (slides) | Mathieu Hofman
Promise.prototype.then をラップ(プロトタイプ汚染)することを考える。
code: js
const originalThen = Promise.prototype.then;
Promise.prototype.then = function (onFulfilled, onRejected) {
return originalThen.call(this, function (value) {
console.log('fulfilled', value);
return onFulfilled ? onFulfilled.call(this, value) : value;
}, onRejected);
};
実は現状これだけでは不十分で、await した際にラップした "then" が呼ばれない。ラップした方を呼び出すには追加で以下のように "constructor" プロパティも汚染する必要がある。
code: js
Promise.prototype.constructor = Promise.bind(null);
なぜかというと現状 PromiseResolve が「ネイティブの Promise インスタンスであって、"constructor" プロパティがネイティブの Promise と同じであれば "then" メソッドを呼び出さない」ファストパスを通るからである。
PromiseResolve ( C, x ):
1. If IsPromise(x) is true, then
a. Let xConstructor be ? Get(x, "constructor").
b. If SameValue(xConstructor, C) is true, return x.
https://tc39.es/ecma262/2025/multipage/control-abstraction-objects.html#sec-promise-resolve
これを解決するために、"constructor" プロパティを見ていたのを辞めて、C.prototype と x.[[Prototype]] が一致するかを見るように変更する Normative Change。原則承認され、Web 互換性の問題がないかエンジン実装者によるデータ収集が行われる。
Convention: strings-as-enums are kebab-case (PR to normative-conventions.md) | Kevin Gibbons
文字列を列挙型のように扱う API は kebab-case と定める Normative Conventions。現状以下のメソッドが当てはまる。
Atomics.waitの返り値: "not-equal", "ok", or "timed-out"
Uint8Array.prototype.setFromBase64 の引数: "loose", "strict", or "stop-before-partial"
承認された。ただし ECMA-402 (Intl) では慣習的にすでに camelCase を使っているため、あくまで ECMA-262 に対してのみ採用される。
Increase limits on Intl MV with discussion of how and when to set bounds in the spec (slides) | Shane F Carr
Intl の API に文字列で数値を極端に大きい値や小さい値を渡したときの範囲制限が定まっている(Intl Mathematical Value)。
https://gyazo.com/4c8befc60d603884a6232d1699433948
現状この制限範囲では Decimal128 に対応できない問題があるため、制限を緩和する Normative Change が提案された。指数部が [-10000, 10000) の範囲となる数値を扱えるようになる。承認された。
それはそれとして Mathematical Value と言う名前で範囲が制限されるのはどうなのかという議論も起きた。
Stage 4 (ES2026)
N/A
Stage 3
Temporal update and normative change (slides) | Philip Chimento
現在の実装状況
https://gyazo.com/8f510492b4cabaa9160ce6d431798469
あとは以下が満たされれば Stage 4 になる:
Intl era and month code が Stage 3 になる
V8 のフラグが外れる
test262 で一部マージされていない PR を取り込み、実装側でも対応する
Non-extensible Applies to Private for stage 3 (slides.key, slides.pdf) | Mark Miller
Object.preventExtensions されたオブジェクトに Private State を付与できなくする提案。Stage 3 になった。
Stage 2.7
Intl Era Month Code Stage 2.7 Update (slides) | Ben Allen
閏月を扱う提案。いくつか Normative Change があった。test262 を進める。
sosukesuzuki さんいわく、ICU4X には実装されているが ICU4C には実装されていないらしく、今後実装者が困ることになるかもしれないとのこと。
Import Bytes for Stage 2.7 (slides) | Steven Salat
バイト列を読み込む提案。
code: js
import bytes from "./photo.png" with { type: "bytes" };
const bytes = import("./photo.png", { with: { type: "bytes" } });
Stage 2.7 になった。依存する Immutable ArrayBuffer の提案待ちになる。
Iterator Chunking for Stage 2.7 (slides) | Michael Ficarra (or KG as backup)
Iterator.prototype.{chunks,windows} の提案。もともと提案されていた sliding メソッドはwindows に統合され、第二引数に渡す文字列で動作が切り替わる。なお Atomics.wait などに合わせて kebab-case である "only-full", "allow-partial" に変更された。
Stage 2.7 になった。
Stage 2
Deferred re-exports update (slides) | Nicolò Ribaudo
code: js
export defer { foo, bar } from "./specifier";
spec text ができた状況。
AsyncContext yield* behavior (draft commit, slides) | Nicolò Ribaudo or Andreu Botella
今の仕様だと Generator Functions で yield や yield* されるたびに AsyncContextSnapshot を作るようになっている。yield* についてはイテレート単位でスナップショットを作るようにしたほうがいいのではと提案され、承認された。
Native Promise Predicate for stage 1 or 2 (spec, slides) | Mathieu Hofman
Promise.isPromise の提案。Stage 2 になった。
Stage 1
Update on proposal-await-dictionary (spec, slides) | Ashley Claymore
Promise.allKeyed の提案。Promise.allSettledKeyed も追加したり、メソッドではなくシンタックスにしたりと議論されている。
code: js
await const session = getSession(), connection = getConnection();
Promise.allSettledKeyed は追加するが、この提案で新しいシンタックスを追加しない方針になった。
Update on proposal-module-global (slides) | ZB Tenerowicz and Kris Kowal
同じ Realm 内で新しいグローバルスコープを作れるようにする提案。API をどうするか議論中。
https://gyazo.com/a1c8e25693f604a28c353f993f3465fb
Compartment の提案に統合する方向性になっている。新しい Realm (Intrinsic) を作らないため ShadowRealm に比べて軽量に作れる(実際に Moddable XS で実行時オーバーヘッドがないことが確認された)と主張される一方で、JIT を含むエンジンの実装者からは複雑性やパフォーマンスへの懸念が出された。
Amount for Stage 2 (slides, slides) | Ben Allen
NaN, Infinity, -0 の扱いについて議論中。現状 new Amount("1.2", { unit: "kg" }) のように初期化しているが、新たに文字列フォーマットを定めるかどうがも話されている(例: new Amount("1.2[kg]"))。
V8 チームからいくつか懸念点が出された:
意図せず Decimal の代替として悪用されてしまうかもしれない
命名の問題(HTML 側で <amount> の提案があるため Amount というクラスになっている)
数値変換メソッドをいれるかどうか
ファーストクラスとして提供してよいか
Array.prototype.pushAll for Stage 1 (slides) | Daniel Rosenwasser
Array.prototype.push の配列版である Array.prototype.pushAll の提案。Stage 1 になった。
Native Promise Adoption for stage 1 (spec, slides) | Mathieu Hofman
await や Array.fromAsync にネイティブの Promise を渡すとなるべくネイティブの %Promise%.prototype.then と同じ動作が採用されるようになっているが、一方で Promise のコンストラクタや Promise.withResolvers, return await で使われる Promise Resolve Functions では必ず "then" メソッドを呼び出すようになっていて一貫性がない。後者でもなるべくネイティブの方を採用するようにする提案。
Stage 1 になった。
Stage 0
N/A
Withdrown
N/A
その他
How Websites are Put Together (slides) | Kevin Gibbons
大規模なサイトではサードパーティスクリプトが含まれる関係もあって、Secure ECMAScript lockdown() のようにプロトタイプを凍結するといったアプローチを取るのが不可能。Compartments のように環境を分ける実装をするほうが良いだろうという話。
Proposal: JSON Schema Standardization under Ecma International
JSON Schema コミュニティがやっていた作業を Ecma に移す取り組みがなされている。
総括
今回は Promise の一貫性のない仕様を修正する変更や提案、昨今のサプライチェーン攻撃に対抗するために Compartments を進めていきたい話が主なトピックだった。
#ECMAScript