Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TypeScriptエンジニアのためのWASMランタイム入門:AssemblyScriptから...

 TypeScriptエンジニアのためのWASMランタイム入門:AssemblyScriptから理解するメモリの実態(ayano)

TSKaigi2026のDay1 / 17:20 ~ 17:50 (Leveragesトラック)の発表資料です。

https://2026.tskaigi.org/talks/28

https://zenn.dev/yuki_ayano/articles/tech-ts-wasm-runtime-intro

--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---

TypeScriptは高水準言語であり、その実行時のメモリ構造はJavaScriptエンジンに依存しています。そのため、通常はオブジェクトや配列がどのようにメモリ上に配置されているかを意識する機会はほとんどありません。本トークでは、TypeScriptに近い構文からWebAssemblyを生成するAssemblyScriptを題材に、「高水準なコードが低レイヤーの線形メモリにどのように配置されるか」を具体的に解説します。

特に以下にフォーカスします:

- WASMの線形メモリモデルの基本
- AssemblyScriptにおけるオブジェクトレイアウトの実態
- classインスタンスがどのようにメモリ上に配置されるか
- 配列(ArrayBuffer / TypedArray含む)の内部構造

Avatar for Tkoya

Tkoya

May 21, 2026

More Decks by Tkoya

Other Decks in Technology

Transcript

  1. TypeScriptではメモリを⾒ない TypeScriptでは p.x と書くだけで済むが、WASMでは「どのアドレスの何バイト ⽬を読むか」という話になる TypeScriptの場合 ➔ JavaScriptエンジン が よしなにする

    WASMの場合 ➔ 線形メモリ上のバイト列 として扱われる TSKaigi 2026@Day1 / 17:20 ~ 17:50 class Point { constructor( public x: number, public y: number, ) {} } const p = new Point(10, 20); 2
  2. AssemblyScripとは TSKaigi 2026@Day1 / 17:20 ~ 17:50 class User {

    id: i32; score: f64; } TypeScriptに近い構⽂でWASMを⽣成できる⾔語で、⾒た⽬はTypeScriptの 親戚ぽいが、実体としてはWASMのメモリモデルにかなり近い • TypeScriptよりも低レイヤーの型を明⽰的に扱う • オブジェクトや配列の実体が異なる ◦ TypeScript :JavaScriptエンジンのオブジェクトとして存在する ◦ AssemblyScript:AssemblyScriptのランタイムが管理する 5
  3. オブジェクトは「ヘッダ + payload」 TypeScriptでは⾒えないが、AssemblyScriptではオブジェクトの前にランタイム 管理⽤の情報が存在する • AssemblyScriptの管理対象オブジェクトにはランタイム⽤ヘッダがある • GC情報、型ID、サイズなどがpayloadの前に置かれる •

    オブジェクト参照はヘッダではなくpayload先頭を指す TSKaigi 2026@Day1 / 17:20 ~ 17:50 +-----------+----------+-----------+--------+---------+------------------+ | mmInfo | gcInfo | gcInfo2 | rtId | rtSize | payload ... | +-----------+----------+-----------+--------+---------+------------------+ -20 -16 -12 -8 -4 0 6
  4. classインスタンスのフィールド配置 vec.x は、低レイヤーでは i32.load(ptr + 0) のような読み取りとして理解できる TSKaigi 2026@Day1 /

    17:20 ~ 17:50 7 class Vec2 { x: i32; y: i32; constructor(x: i32, y: i32) { this.x = x; this.y = y; } } export function makeVec2Ptr(x: i32, y: i32): usize { return changetype<usize>(new Vec2(x, y)); }
  5. classインスタンスのフィールド配置 vec.x は、低レイヤーでは i32.load(ptr + 0) のような読み取りとして理解できる • classのフィールドはpayload内にオフセット付きで並ぶ •

    x: i32, y: i32 なら ptr + 0, ptr + 4 • フィールドアクセスは「参照 + オフセット + load」 TSKaigi 2026@Day1 / 17:20 ~ 17:50 8 +--------------------+---------------------+ | 0x11223344 | 0x55667788 | +--------------------+---------------------+ +0 +4 vec.x => i32.load(ptr + 0) vec.y => i32.load(ptr + 4)
  6. ArrayBuffer / TypedArray / Array<T> の違い AssemblyScriptには、いくつか配列っぽいものがあり、バッファ参照や⻑さなど のメタデータが異なる TSKaigi 2026@Day1

    / 17:20 ~ 17:50 11 種類 説明 ArrayBuffer 生のバイト列 TypedArray ArrayBufferへの型付きビュー Array<T> buffer, dataStart, byteLength, lengthを持つリッチな配列
  7. ArrayBuffer / TypedArray / Array<T> の違い AssemblyScriptには、いくつか配列っぽいものがあり、バッファ参照や⻑さなど のメタデータが異なる TSKaigi 2026@Day1

    / 17:20 ~ 17:50 12 ArrayBuffer +--------+--------+--------+--------+ | byte | byte | byte | byte | +--------+--------+--------+--------+ ArrayBuffer ➔ ペイロードはそのまま未型付けのデータ領域
  8. ArrayBuffer / TypedArray / Array<T> の違い AssemblyScriptには、いくつか配列っぽいものがあり、バッファ参照や⻑さなど のメタデータが異なる TSKaigi 2026@Day1

    / 17:20 ~ 17:50 13 TypedArray object +----------------+----------------+---------------------+ | buffer ref | dataStart | byteLength | +----------------+----------------+---------------------+ TypedArray ➔ ArrayBuffer を特定の型の連続データとして⾒れるもの
  9. ArrayBuffer / TypedArray / Array<T> の違い AssemblyScriptには、いくつか配列っぽいものがあり、バッファ参照や⻑さなど のメタデータが異なる TSKaigi 2026@Day1

    / 17:20 ~ 17:50 14 Array<T> object +----------------+------------+-----------------+----------+ | buffer ref | dataStart | byteLength | length | +--------------+--------------+-----------------+----------+ Array<T> ➔ TypedArray に近い情報に加えて、さらに length を持つ