รูปแบบข้อความ WAT
WebAssembly มีอยู่สองรูปแบบ: binary format ที่กระชับ (.wasm) ที่ browser เอ็กซิคิวต์ และรูปแบบข้อความที่มนุษย์อ่านได้เรียกว่า WAT — WebAssembly Text format ทั้งสองรูปแบบเทียบเท่ากันแบบ 1:1 ทุกโครงสร้างใน WAT มีคู่เทียบใน binary ที่ตรงกันเป๊ะ
คุณแทบจะไม่เคยเขียน WAT ในงาน production คอมไพเลอร์สำหรับ C, Rust, Go และภาษาอื่น ๆ จะสร้าง .wasm ออกมาโดยตรง แต่การอ่านและเขียน WAT ด้วยมือเป็นวิธีที่เร็วที่สุดในการสร้างแบบจำลองทางความคิดที่แม่นยำว่า WebAssembly ทำงานอย่างไรจริง ๆ
WAT กลายเป็นฟังก์ชันที่รันได้อย่างไร
หัวข้อที่มีชื่อว่า “WAT กลายเป็นฟังก์ชันที่รันได้อย่างไร”ไปป์ไลน์จากข้อความต้นฉบับไปสู่ฟังก์ชัน JS ที่เรียกได้มีสี่ขั้นตอน
flowchart LR A["WAT source\n(text string)"] --> B["compileWat()\n→ Uint8Array"] B --> C["WebAssembly.instantiate()\n→ instance"] C --> D["instance.exports\n(exported functions)"] D --> E["JS call\nconsole.log(add(2,3))"]
- WAT source — สตริงข้อความที่คุณเขียนเอง (หรือไฟล์
.watบนดิสก์) - คอมไพล์เป็นไบต์ — ฟังก์ชันช่วย
compileWat()ใน sandbox นี้จะเรียก WebAssembly Binary Toolkit (WABT) และคืนค่าเป็นUint8Arrayของไบต์.wasm - Instantiate —
WebAssembly.instantiate(bytes, {})จะแยกวิเคราะห์และ JIT-คอมไพล์ไบต์เหล่านั้น แล้วคืนค่าเป็นWebAssembly.Instance - เรียก —
instance.exports.add(2, 3)เรียกฟังก์ชันที่ export มาจาก JavaScript
module WAT ที่เล็กที่สุด
หัวข้อที่มีชื่อว่า “module WAT ที่เล็กที่สุด”นี่คือโปรแกรม WAT ที่เล็กที่สุดที่มีประโยชน์ — ฟังก์ชัน add ที่รับจำนวนเต็ม 32 บิตสองตัวและคืนค่าผลรวมของตัวเอง:
(module (func (export "add") (param $a i32) (param $b i32) (result i32) local.get $a local.get $b i32.add))สิ่งที่ควรสังเกตมีอยู่ไม่กี่อย่าง:
- โปรแกรมทั้งหมดถูกห่อหุ้มไว้ใน
(module ...) (func ...)ประกาศฟังก์ชัน แอตทริบิวต์(export "add")ทำให้เรียกได้จาก JavaScript(param $a i32)และ(param $b i32)ประกาศพารามิเตอร์ที่มีชื่อสองตัวชนิดi32(จำนวนเต็ม 32 บิต)(result i32)ประกาศชนิดของค่าที่คืนกลับ- ตัวบอดี้เป็นลำดับของคำสั่งแบบ stack
local.get $aจะ push ค่าของ$a,local.get $bจะ push$b, และi32.addจะ pop ทั้งสองค่าแล้ว push ผลรวมของตัวเอง
WebAssembly ใช้แบบจำลอง stack machine คำสั่งจะ pop อินพุตของตัวเองออกจาก stack แล้ว push ผลลัพธ์กลับไป เมื่อสิ้นสุดฟังก์ชัน ค่าตัวเดียวที่เหลืออยู่บน stack คือค่าที่คืนกลับ
ลองรันดู
หัวข้อที่มีชื่อว่า “ลองรันดู”เอดิเตอร์ด้านล่างมีตัวอย่าง add เดียวกันที่เชื่อมต่อเป็น JavaScript ที่รันได้ คลิก Run เพื่อคอมไพล์ WAT แล้วเรียกฟังก์ชัน