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