ข้ามไปยังเนื้อหา

Linear Memory

ฟังก์ชัน WebAssembly ทำงานกับตัวเลขเท่านั้น — i32, i64, f32 และ f64 นั่นคือชุดชนิดข้อมูลทั้งหมด ไม่มี string type, array type หรือ struct type แล้วจะส่ง string จาก JavaScript ไปยังฟังก์ชัน Wasm หรือสร้าง dynamic array ภายใน Wasm ได้อย่างไร? คำตอบคือ linear memory

Linear memory คือกลุ่มของ byte ที่ต่อเนื่องกันซึ่งทั้ง WebAssembly และ JavaScript สามารถอ่านและเขียนได้ ฝั่ง WebAssembly เข้าถึงด้วยคำสั่งอย่าง i32.load และ i32.store ส่วนฝั่ง JavaScript จะได้รับ ArrayBuffer ธรรมดา — เป็น object เดียวกับที่ใช้กับ TypedArray views อย่าง Uint8Array และ Int32Array

คำว่า “linear” หมายความว่า address space เป็นแบบ flat และหนึ่งมิติ: ทุก byte มี numeric offset เริ่มต้นที่ 0 และ address จะเพิ่มขึ้นตามลำดับจนถึงขนาดปัจจุบันของ buffer ไม่มี pointer-to-pointer, ไม่มี heap metadata ที่มองเห็นได้ มีแค่ raw byte ที่ numeric offset

flowchart LR
  A["WebAssembly\n(i32.load / i32.store)"] --> B["Shared ArrayBuffer\n(linear memory)"]
  B --> A
  C["JavaScript\n(typed array views)"] --> B
  B --> C
Wasm และ JS แชร์ ArrayBuffer เดียวกัน

Value model ที่เป็นตัวเลขล้วนของ Wasm เป็นการออกแบบโดยเจตนา เพื่อให้ instruction set เล็กกะทัดรัด execution engine เรียบง่าย และ performance คาดเดาได้ แต่โปรแกรมจริงต้องการข้อมูลที่ซับซ้อน — UTF-8 string, byte array, struct ที่มีหลาย field Linear memory จึงเป็นทางออก:

  • String ถูกเก็บเป็น sequence ของ UTF-8 byte ที่ offset ใดออฟเซ็ตหนึ่ง โดยส่ง offset (เป็น i32) และความยาว byte (อีก i32 หนึ่ง) ไปยังฟังก์ชัน Wasm แทนที่จะส่ง string โดยตรง
  • Array คือค่าหลายตัวที่เขียนต่อเนื่องกันเริ่มจาก base address
  • Struct คือ field ที่อัดรวมกันที่ offset คงที่จาก base address เหมือน C struct พอดี

JavaScript และ Wasm ต่างถือ reference ไปยัง ArrayBuffer เดียวกัน ดังนั้นการเขียนจากฝั่งใดก็ตามจะมองเห็นได้จากอีกฝั่งทันที — ไม่มี serialization, ไม่มีการ copy

module ด้านล่างประกาศ memory หนึ่งหน้าและ export เพื่อให้ JavaScript ตรวจสอบได้ ฟังก์ชัน store42 เขียนตัวเลข 42 เป็น little-endian integer 4 byte ที่ byte offset 0 จากนั้น JavaScript สร้าง Int32Array view บน buffer และอ่านค่านั้นกลับมา

WebAssembly
WebAssembly linear memory คืออะไร?
ทำไม string ต้องเก็บใน linear memory แทนที่จะส่งตรงไปยังฟังก์ชัน Wasm?
JavaScript object ใดที่ทำหน้าที่ backup WebAssembly linear memory?