Slide 1

Slide 1 text

TypeScriptエンジニアのための WASMランタイム入門 ayano

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

WASMの線形メモリモデルについて 「プログラムが利⽤する連続したフラットなバイト列のメモリ領域」で、オブ ジェクトも配列もこのバイト列のどこかに置かれ、読み書きされる 例)i32.load ;; あるアドレスから4バイト読んで i32 として扱う   i32.store ;; あるアドレスに i32 を4バイト書き込む TSKaigi 2026@Day1 / 17:20 ~ 17:50 const memory = instance.exports.memory as WebAssembly.Memory; const bytes = new Uint8Array(memory.buffer); 3

Slide 4

Slide 4 text

AssemblyScriptとは TypeScriptに近い構⽂でWASMを⽣成できる⾔語で、⾒た⽬はTypeScriptの 親戚ぽいが、実体としてはWASMのメモリモデルにかなり近い ● TypeScriptよりも低レイヤーの型を明⽰的に扱う ● オブジェクトや配列の実体が異なる TSKaigi 2026@Day1 / 17:20 ~ 17:50 export function add(a: i32, b: i32): i32 { return a + b; } 4

Slide 5

Slide 5 text

AssemblyScripとは TSKaigi 2026@Day1 / 17:20 ~ 17:50 class User { id: i32; score: f64; } TypeScriptに近い構⽂でWASMを⽣成できる⾔語で、⾒た⽬はTypeScriptの 親戚ぽいが、実体としてはWASMのメモリモデルにかなり近い ● TypeScriptよりも低レイヤーの型を明⽰的に扱う ● オブジェクトや配列の実体が異なる ○ TypeScript :JavaScriptエンジンのオブジェクトとして存在する ○ AssemblyScript:AssemblyScriptのランタイムが管理する 5

Slide 6

Slide 6 text

オブジェクトは「ヘッダ + 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

Slide 7

Slide 7 text

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(new Vec2(x, y)); }

Slide 8

Slide 8 text

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)

Slide 9

Slide 9 text

パディング:ソースコード通りには詰まらない ⾼⽔準コードでは⾒えないが、低レイヤーではフィールド順や型サイズが実際の メモリ使⽤量に影響する TSKaigi 2026@Day1 / 17:20 ~ 17:50 9 class PadDemo { tag: u8; value: i32; constructor(tag: u8, value: i32) { this.tag = tag; this.value = value; }

Slide 10

Slide 10 text

パディング:ソースコード通りには詰まらない ⾼⽔準コードでは⾒えないが、低レイヤーではフィールド順や型サイズが実際の メモリ使⽤量に影響する ● 低レイヤーのメモリレイアウトでは、型ごとに⾃然な境界に揃えるためのア ラインメントがあるから ● ⾼⽔準なclassも、メモリ上では型サイズ‧オフセット‧paddingを持つ具体 的なレイアウトになる TSKaigi 2026@Day1 / 17:20 ~ 17:50 10 +-----------+--------------------+----------------+ | tag: u8 | padding | value: i32 | +-----------+--------------------+----------------+ +0 +1..+3 +4

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

ArrayBuffer / TypedArray / Array の違い AssemblyScriptには、いくつか配列っぽいものがあり、バッファ参照や⻑さなど のメタデータが異なる TSKaigi 2026@Day1 / 17:20 ~ 17:50 14 Array object +----------------+------------+-----------------+----------+ | buffer ref | dataStart | byteLength | length | +--------------+--------------+-----------------+----------+ Array ➔ TypedArray に近い情報に加えて、さらに length を持つ

Slide 15

Slide 15 text

まとめ:TypeScriptの抽象をバイト列として⾒る TypeScript⾵の⾼⽔準なコードも、WASMの視点では具体的なメモリアクセスと して⾒える ● WASMのメモリは連続したバイト列 ● AssemblyScriptの管理対象オブジェクトは、ランタイム⽤ヘッダ + payload を持つ ● classのフィールドは、 payload内にオフセット付きで配置される ● ArrayBuffer / TypedArray / Array は、それぞれメモリ上での役割が違う TSKaigi 2026@Day1 / 17:20 ~ 17:50 15

Slide 16

Slide 16 text

実験の内容をまとめた記事 実験で使⽤したプログラム