Control Flow — ภาพรวม
WebAssembly ไม่มี goto ไม่มี raw jump address และไม่มี unstructured branch ทุกการถ่ายโอน control จะเกิดขึ้นภายใน labeled construct โดยที่ br ชี้ไปที่ label นั้น — ไม่ใช่ memory address หรือหมายเลขบรรทัด การออกแบบนี้ทำให้ Wasm program ตรวจสอบความถูกต้องได้ในการอ่านเดียว และคอมไพล์ได้อย่างมีประสิทธิภาพบน browser
Structured constructs
หัวข้อที่มีชื่อว่า “Structured constructs”Wasm มี control-flow construct ทั้งหมดสามตัว:
block— กลุ่มที่เดินไปข้างหน้าเท่านั้นbr $labelจะออกจาก block โดยกระโดดไปยังคำสั่งที่อยู่ หลังendที่ปิด ให้คิดว่าเป็น labeled breakloop— backward-branch targetbr $labelกระโดดไปยัง จุดเริ่มต้น ของ loop ทำให้วนซ้ำ การออกจาก loop ต้องกระโดดไปที่ outer label หรือตกออกจากส่วนท้ายif— conditional branch popi32จาก stack ถ้าไม่ใช่ศูนย์จะรันthenarm ถ้าไม่ก็รันelsearm ที่เป็น optional
Construct ทั้งสามสามารถมี result type ได้ ทำให้เป็น expression ที่ฝากค่าไว้บน stack
Branch targets และทิศทาง
หัวข้อที่มีชื่อว่า “Branch targets และทิศทาง”ประเด็นสำคัญคือ br ใน Wasm ไม่ใช่การกระโดดไปที่ address แต่เป็นการกระโดด เทียบกับ nesting structure br $b ภายใน block $b จะออกจาก block นั้น แต่ br $l เดียวกันภายใน loop $l จะวนซ้ำ loop นั้น
flowchart LR A["block $b\n ...body...\n br $b"] --> B["jumps to END\nof block"] C["loop $l\n ...body...\n br_if $l"] --> D["jumps to START\nof loop"]
br_if คือ conditional variant — pop i32 condition และกระโดดเฉพาะเมื่อค่าไม่ใช่ศูนย์
สิ่งที่ module นี้ครอบคลุม
หัวข้อที่มีชื่อว่า “สิ่งที่ module นี้ครอบคลุม”Module นี้จะอธิบาย construct แต่ละตัวอย่างละเอียด:
blockและbr— ใช้ labeled break เพื่อออกจากลำดับคำสั่งก่อนกำหนดloopและbr_if— การเขียน counted และ conditional loopif / else— conditional execution พร้อม optional result values
Early exit ด้วย block และ br
หัวข้อที่มีชื่อว่า “Early exit ด้วย block และ br”การใช้ block ที่ง่ายที่สุดคือ early-exit pattern ฟังก์ชันด้านล่าง push 42 แล้วกระโดดออกจาก block ทันที และ i32.const 99 หลัง branch จะไม่ถูกเรียกใช้งานเลย
(module (func (export "earlyExit") (result i32) (block $b (result i32) i32.const 42 br $b i32.const 99) ;; never reached ))block มี result type เป็น i32 เมื่อ br $b ทำงาน ค่า 42 อยู่บน stack แล้วและกลายเป็น result ของ block expression — และด้วยเหตุนี้จึงเป็นค่าที่ฟังก์ชันคืนกลับ