Skip to main content

wasi_assembler/formats/wasm/reader/
mod.rs

1#![doc = include_str!("readme.md")]
2
3use crate::{
4    formats::wasm::WasmReadConfig,
5    program::{WasiProgram, WasmInfo},
6};
7use byteorder::LittleEndian;
8use gaia_types::{BinaryReader, GaiaDiagnostics, GaiaError};
9use std::{
10    cell::{OnceCell, RefCell},
11    io::{Read, Seek},
12};
13
14/// WASM LEB128 reader helper
15fn read_u32_leb128<R: Read>(reader: &mut R) -> std::io::Result<u32> {
16    let mut result = 0u32;
17    let mut shift = 0;
18    loop {
19        let mut byte = [0u8; 1];
20        reader.read_exact(&mut byte)?;
21        let b = byte[0];
22        result |= ((b & 0x7F) as u32) << shift;
23        if b & 0x80 == 0 {
24            break;
25        }
26        shift += 7;
27        if shift >= 32 {
28            return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "LEB128 value too large for u32"));
29        }
30    }
31    Ok(result)
32}
33
34fn read_i32_leb128<R: Read>(reader: &mut R) -> std::io::Result<i32> {
35    let mut result = 0i32;
36    let mut shift = 0;
37    let mut byte;
38    loop {
39        let mut buf = [0u8; 1];
40        reader.read_exact(&mut buf)?;
41        byte = buf[0];
42        result |= ((byte & 0x7F) as i32) << shift;
43        shift += 7;
44        if byte & 0x80 == 0 {
45            break;
46        }
47    }
48    if shift < 32 && (byte & 0x40) != 0 {
49        result |= !0 << shift;
50    }
51    Ok(result)
52}
53
54fn read_i64_leb128<R: Read>(reader: &mut R) -> std::io::Result<i64> {
55    let mut result = 0i64;
56    let mut shift = 0;
57    let mut byte;
58    loop {
59        let mut buf = [0u8; 1];
60        reader.read_exact(&mut buf)?;
61        byte = buf[0];
62        result |= ((byte & 0x7F) as i64) << shift;
63        shift += 7;
64        if byte & 0x80 == 0 {
65            break;
66        }
67    }
68    if shift < 64 && (byte & 0x40) != 0 {
69        result |= !0 << shift;
70    }
71    Ok(result)
72}
73
74/// wasm lazy reader
75#[derive(Debug)]
76pub struct WasmReader<'config, R> {
77    _config: &'config WasmReadConfig,
78    reader: RefCell<BinaryReader<R, LittleEndian>>,
79    view: OnceCell<WasmInfo>,
80    program: OnceCell<WasiProgram>,
81}
82
83impl WasmReadConfig {
84    pub fn as_reader<R: Read + Seek>(&self, reader: R) -> WasmReader<'_, R> {
85        WasmReader::new(reader, self)
86    }
87}
88
89impl<'config, R> WasmReader<'config, R> {
90    pub fn new(reader: R, config: &'config WasmReadConfig) -> Self {
91        Self {
92            reader: RefCell::new(BinaryReader::new(reader)),
93            view: Default::default(),
94            program: Default::default(),
95            _config: config,
96        }
97    }
98    pub fn finish(mut self) -> GaiaDiagnostics<WasiProgram>
99    where
100        R: Read + Seek,
101    {
102        match self.get_program() {
103            Ok(_) => {
104                let errors = vec![]; // self.reader.borrow_mut().take_errors();
105                GaiaDiagnostics { result: self.program.take().ok_or(GaiaError::custom_error("unreachable")), diagnostics: errors }
106            }
107            Err(e) => {
108                let errors = vec![]; // self.reader.borrow_mut().take_errors();
109                GaiaDiagnostics { result: Err(e), diagnostics: errors }
110            }
111        }
112    }
113}
114
115impl<'config, R: Read + Seek> WasmReader<'config, R> {
116    pub fn get_program(&self) -> Result<&WasiProgram, GaiaError> {
117        self.program.get_or_try_init(|| self.read_program())
118    }
119    fn read_program(&self) -> Result<WasiProgram, GaiaError> {
120        let mut reader = self.reader.borrow_mut();
121
122        // 重新定位到文件开头
123        reader.seek(std::io::SeekFrom::Start(0))?;
124
125        // 验证 WASM 文件头
126        self.validate_wasm_header(&mut reader)?;
127
128        // 创建核心模块程序
129        let mut program = crate::program::WasiProgram::new_core_module();
130
131        // 解析各个段
132        self.parse_sections(&mut reader, &mut program)?;
133
134        Ok(program)
135    }
136
137    fn validate_wasm_header(&self, reader: &mut BinaryReader<R, LittleEndian>) -> Result<(), GaiaError> {
138        // 读取并验证 WASM 文件头
139        let magic = reader.read_u32()?;
140        if magic != 0x6D736100 {
141            // "\0asm" in little-endian
142            return Err(GaiaError::invalid_data("Invalid WASM file magic number"));
143        }
144
145        let version = reader.read_u32()?;
146        if version != 1 {
147            return Err(GaiaError::invalid_data(&format!("Unsupported WASM version: {}", version)));
148        }
149
150        Ok(())
151    }
152
153    fn parse_sections(
154        &self,
155        reader: &mut BinaryReader<R, LittleEndian>,
156        program: &mut crate::program::WasiProgram,
157    ) -> Result<(), GaiaError> {
158        while let Ok(section_id) = reader.read_u8() {
159            let section_size = read_u32_leb128(reader)?;
160
161            match section_id {
162                0 => self.read_custom_section(reader, program, section_size)?,
163                1 => self.read_type_section(reader, program)?,
164                2 => self.read_import_section(reader, program)?,
165                3 => self.read_function_section(reader, program)?,
166                4 => self.read_table_section(reader, program)?,
167                5 => self.read_memory_section(reader, program)?,
168                6 => self.read_global_section(reader, program)?,
169                7 => self.read_export_section(reader, program)?,
170                8 => self.read_start_section(reader, program)?,
171                9 => self.skip_section(reader, section_size)?, // Element section
172                10 => self.read_code_section(reader, program)?,
173                11 => self.skip_section(reader, section_size)?, // Data section
174                _ => self.skip_section(reader, section_size)?,  // Unknown section
175            }
176        }
177        Ok(())
178    }
179
180    fn read_custom_section(
181        &self,
182        reader: &mut BinaryReader<R, LittleEndian>,
183        program: &mut crate::program::WasiProgram,
184        section_size: u32,
185    ) -> Result<(), GaiaError> {
186        let name_len = read_u32_leb128(reader)?;
187        let mut name_bytes = vec![0u8; name_len as usize];
188        reader.read_exact(&mut name_bytes)?;
189        let name = String::from_utf8_lossy(&name_bytes).to_string();
190
191        let data_len = section_size - name_len - gaia_types::BinaryReader::<R, LittleEndian>::leb128_size(name_len);
192        let mut data = vec![0u8; data_len as usize];
193        reader.read_exact(&mut data)?;
194
195        program.custom_sections.push(crate::program::WasiCustomSection { name, data });
196        Ok(())
197    }
198
199    fn read_start_section(
200        &self,
201        reader: &mut BinaryReader<R, LittleEndian>,
202        program: &mut crate::program::WasiProgram,
203    ) -> Result<(), GaiaError> {
204        let start_func = read_u32_leb128(reader)?;
205        program.start_function = Some(start_func);
206        Ok(())
207    }
208
209    pub fn get_view(&self) -> Result<&WasmInfo, GaiaError> {
210        self.view.get_or_try_init(|| self.read_view())
211    }
212
213    fn read_view(&self) -> Result<WasmInfo, GaiaError> {
214        let mut reader = self.reader.borrow_mut();
215
216        // 重新定位到文件开头
217        reader.seek(std::io::SeekFrom::Start(0))?;
218
219        // 读取并验证 WASM 文件头
220        let magic = reader.read_u32()?;
221        if magic != 0x6D736100 {
222            // "\0asm" in little-endian
223            return Err(GaiaError::invalid_data("Invalid WASM file magic number"));
224        }
225
226        let _version = reader.read_u32()?;
227
228        Ok(WasmInfo {
229            magic_head: [0x00, 0x61, 0x73, 0x6D], // "\0asm"
230        })
231    }
232
233    // Helper methods for reading WASM format
234    fn skip_section(&self, reader: &mut BinaryReader<R, LittleEndian>, size: u32) -> Result<(), GaiaError> {
235        let mut buffer = vec![0u8; size as usize];
236        reader.read_exact(&mut buffer)?;
237        Ok(())
238    }
239
240    fn read_type_section(
241        &self,
242        reader: &mut BinaryReader<R, LittleEndian>,
243        program: &mut crate::program::WasiProgram,
244    ) -> Result<(), GaiaError> {
245        let count = read_u32_leb128(reader)?;
246
247        for _ in 0..count {
248            let form = reader.read_u8()?;
249            if form != 0x60 {
250                // Function type
251                return Err(GaiaError::invalid_data("Unsupported type form"));
252            }
253
254            let param_count = read_u32_leb128(reader)?;
255            let mut params = Vec::new();
256            for _ in 0..param_count {
257                let param_type = self.read_value_type(reader)?;
258                params.push(param_type);
259            }
260
261            let result_count = read_u32_leb128(reader)?;
262            let mut results = Vec::new();
263            for _ in 0..result_count {
264                let result_type = self.read_value_type(reader)?;
265                results.push(result_type);
266            }
267
268            program.function_types.push(crate::program::WasiFunctionType { params, results });
269        }
270
271        Ok(())
272    }
273
274    fn read_type(&self, reader: &mut BinaryReader<R, LittleEndian>) -> Result<crate::program::WasiType, GaiaError> {
275        let tag = reader.read_u8()?;
276        match tag {
277            0x7F | 0x7E | 0x7D | 0x7C | 0x7B | 0x7A | 0x79 | 0x78 | 0x77 | 0x76 | 0x75 | 0x74 | 0x73 => {
278                let prim = match tag {
279                    0x7F => crate::program::WasiPrimitiveType::Bool,
280                    0x7E => crate::program::WasiPrimitiveType::S8,
281                    0x7D => crate::program::WasiPrimitiveType::U8,
282                    0x7C => crate::program::WasiPrimitiveType::S16,
283                    0x7B => crate::program::WasiPrimitiveType::U16,
284                    0x7A => crate::program::WasiPrimitiveType::S32,
285                    0x79 => crate::program::WasiPrimitiveType::U32,
286                    0x78 => crate::program::WasiPrimitiveType::S64,
287                    0x77 => crate::program::WasiPrimitiveType::U64,
288                    0x76 => crate::program::WasiPrimitiveType::F32,
289                    0x75 => crate::program::WasiPrimitiveType::F64,
290                    0x74 => crate::program::WasiPrimitiveType::Char,
291                    0x73 => crate::program::WasiPrimitiveType::String,
292                    _ => unreachable!(),
293                };
294                Ok(crate::program::WasiType::Primitive(prim))
295            }
296            0x72 => {
297                // record
298                let count = read_u32_leb128(reader)?;
299                let mut fields = Vec::new();
300                for _ in 0..count {
301                    let name_len = read_u32_leb128(reader)?;
302                    let mut name_bytes = vec![0u8; name_len as usize];
303                    reader.read_exact(&mut name_bytes)?;
304                    let name = String::from_utf8_lossy(&name_bytes).to_string();
305                    let field_type = self.read_type(reader)?;
306                    fields.push(crate::program::WasiRecordField { name, field_type });
307                }
308                Ok(crate::program::WasiType::Record(fields))
309            }
310            0x69 => {
311                // future (WASIp3)
312                let has_type = reader.read_u8()?;
313                let inner = if has_type == 0x01 { Some(Box::new(self.read_type(reader)?)) } else { None };
314                Ok(crate::program::WasiType::Future(inner))
315            }
316            0x68 => {
317                // stream (WASIp3)
318                let has_type = reader.read_u8()?;
319                let inner = if has_type == 0x01 { Some(Box::new(self.read_type(reader)?)) } else { None };
320                Ok(crate::program::WasiType::Stream(inner))
321            }
322            _ => Err(GaiaError::invalid_data(&format!("Unsupported type tag: 0x{:02X}", tag))),
323        }
324    }
325
326    fn read_canon_options(
327        &self,
328        reader: &mut BinaryReader<R, LittleEndian>,
329    ) -> Result<Vec<crate::program::WasiCanonOption>, GaiaError> {
330        let count = read_u32_leb128(reader)?;
331        let mut options = Vec::new();
332        for _ in 0..count {
333            let tag = reader.read_u8()?;
334            match tag {
335                0x00 => {
336                    let enc_tag = reader.read_u8()?;
337                    let enc = match enc_tag {
338                        0x00 => "utf8",
339                        0x01 => "utf16",
340                        0x02 => "compact-utf16",
341                        _ => "utf8",
342                    };
343                    options.push(crate::program::WasiCanonOption::StringEncoding(enc.to_string()));
344                }
345                0x01 => {
346                    let _mem_index = read_u32_leb128(reader)?;
347                    options.push(crate::program::WasiCanonOption::Memory("0".to_string()));
348                }
349                0x02 => {
350                    let _realloc_index = read_u32_leb128(reader)?;
351                    options.push(crate::program::WasiCanonOption::Realloc("0".to_string()));
352                }
353                0x04 => {
354                    // async (WASIp3)
355                    options.push(crate::program::WasiCanonOption::Async);
356                }
357                0x05 => {
358                    // callback (WASIp3)
359                    let _callback_index = read_u32_leb128(reader)?;
360                    options.push(crate::program::WasiCanonOption::Callback("0".to_string()));
361                }
362                _ => return Err(GaiaError::invalid_data(&format!("Unsupported canon option tag: 0x{:02X}", tag))),
363            }
364        }
365        Ok(options)
366    }
367
368    fn read_value_type(&self, reader: &mut BinaryReader<R, LittleEndian>) -> Result<crate::program::WasmValueType, GaiaError> {
369        let type_byte = reader.read_u8()?;
370        crate::program::WasmValueType::try_from(type_byte)
371    }
372
373    fn read_import_section(
374        &self,
375        reader: &mut BinaryReader<R, LittleEndian>,
376        program: &mut crate::program::WasiProgram,
377    ) -> Result<(), GaiaError> {
378        let count = read_u32_leb128(reader)?;
379
380        for _ in 0..count {
381            // 读取模块名
382            let module_len = read_u32_leb128(reader)?;
383            let mut module_bytes = vec![0u8; module_len as usize];
384            reader.read_exact(&mut module_bytes)?;
385            let module = String::from_utf8_lossy(&module_bytes).to_string();
386
387            // 读取字段名
388            let field_len = read_u32_leb128(reader)?;
389            let mut field_bytes = vec![0u8; field_len as usize];
390            reader.read_exact(&mut field_bytes)?;
391            let field = String::from_utf8_lossy(&field_bytes).to_string();
392
393            let import_type = self.read_import_type(reader)?;
394
395            program.imports.push(crate::program::WasiImport { module, field, import_type });
396        }
397
398        Ok(())
399    }
400
401    fn read_import_type(
402        &self,
403        reader: &mut BinaryReader<R, LittleEndian>,
404    ) -> Result<crate::program::WasmImportType, GaiaError> {
405        let kind = reader.read_u8()?;
406        match kind {
407            0x00 => {
408                // Function
409                let type_index = read_u32_leb128(reader)?;
410                Ok(crate::program::WasmImportType::Function { type_index })
411            }
412            0x01 => {
413                // Table
414                let table_type = self.read_table_type(reader)?;
415                Ok(crate::program::WasmImportType::Table { table_type })
416            }
417            0x02 => {
418                // Memory
419                let memory_type = self.read_memory_type(reader)?;
420                Ok(crate::program::WasmImportType::Memory { memory_type })
421            }
422            0x03 => {
423                // Global
424                let global_type = self.read_global_type(reader)?;
425                Ok(crate::program::WasmImportType::Global { global_type })
426            }
427            _ => Err(GaiaError::invalid_data(&format!("Unknown import kind: {}", kind))),
428        }
429    }
430
431    fn read_function_section(
432        &self,
433        reader: &mut BinaryReader<R, LittleEndian>,
434        program: &mut crate::program::WasiProgram,
435    ) -> Result<(), GaiaError> {
436        let count = read_u32_leb128(reader)?;
437
438        for _ in 0..count {
439            let type_index = read_u32_leb128(reader)?;
440            // 创建空的函数,稍后在 code section 中填充
441            program.functions.push(crate::program::WasiFunction { type_index, locals: Vec::new(), body: Vec::new() });
442        }
443
444        Ok(())
445    }
446
447    fn read_table_section(
448        &self,
449        reader: &mut BinaryReader<R, LittleEndian>,
450        program: &mut crate::program::WasiProgram,
451    ) -> Result<(), GaiaError> {
452        let count = read_u32_leb128(reader)?;
453
454        for _ in 0..count {
455            let table_type = self.read_table_type(reader)?;
456            program.tables.push(crate::program::WasiTable { table_type });
457        }
458
459        Ok(())
460    }
461
462    fn read_table_type(&self, reader: &mut BinaryReader<R, LittleEndian>) -> Result<crate::program::WasmTableType, GaiaError> {
463        let element_type = reader.read_u8()?;
464        let element_type = match element_type {
465            0x70 => crate::program::WasmReferenceType::FuncRef,
466            0x6F => crate::program::WasmReferenceType::ExternRef,
467            _ => return Err(GaiaError::invalid_data(&format!("Unknown reference type: 0x{:02X}", element_type))),
468        };
469
470        let limits = self.read_limits(reader)?;
471
472        Ok(crate::program::WasmTableType { element_type, min: limits.0, max: limits.1 })
473    }
474
475    fn read_memory_section(
476        &self,
477        reader: &mut BinaryReader<R, LittleEndian>,
478        program: &mut crate::program::WasiProgram,
479    ) -> Result<(), GaiaError> {
480        let count = read_u32_leb128(reader)?;
481
482        for _ in 0..count {
483            let memory_type = self.read_memory_type(reader)?;
484            program.memories.push(crate::program::WasiMemory { memory_type });
485        }
486
487        Ok(())
488    }
489
490    fn read_memory_type(
491        &self,
492        reader: &mut BinaryReader<R, LittleEndian>,
493    ) -> Result<crate::program::WasmMemoryType, GaiaError> {
494        let limits = self.read_limits(reader)?;
495        Ok(crate::program::WasmMemoryType { min: limits.0, max: limits.1 })
496    }
497
498    fn read_limits(&self, reader: &mut BinaryReader<R, LittleEndian>) -> Result<(u32, Option<u32>), GaiaError> {
499        let flags = reader.read_u8()?;
500        let min = read_u32_leb128(reader)?;
501        let max = if flags & 0x01 != 0 { Some(read_u32_leb128(reader)?) } else { None };
502        Ok((min, max))
503    }
504
505    fn read_global_section(
506        &self,
507        reader: &mut BinaryReader<R, LittleEndian>,
508        program: &mut crate::program::WasiProgram,
509    ) -> Result<(), GaiaError> {
510        let count = read_u32_leb128(reader)?;
511
512        for _ in 0..count {
513            let global_type = self.read_global_type(reader)?;
514            let init_expr = self.read_init_expr(reader)?;
515            program.globals.push(crate::program::WasiGlobal { global_type, init_expr });
516        }
517
518        Ok(())
519    }
520
521    fn read_global_type(
522        &self,
523        reader: &mut BinaryReader<R, LittleEndian>,
524    ) -> Result<crate::program::WasmGlobalType, GaiaError> {
525        let value_type = self.read_value_type(reader)?;
526        let mutability = reader.read_u8()?;
527        let mutable = mutability != 0;
528
529        Ok(crate::program::WasmGlobalType { value_type, mutable })
530    }
531
532    fn read_init_expr(
533        &self,
534        reader: &mut BinaryReader<R, LittleEndian>,
535    ) -> Result<Vec<crate::program::WasiInstruction>, GaiaError> {
536        let mut instructions = Vec::new();
537
538        loop {
539            let opcode = reader.read_u8()?;
540            match opcode {
541                0x41 => {
542                    // i32.const
543                    let value = read_i32_leb128(reader)?;
544                    instructions.push(crate::program::WasiInstruction::I32Const { value });
545                }
546                0x42 => {
547                    // i64.const
548                    let value = read_i64_leb128(reader)?;
549                    instructions.push(crate::program::WasiInstruction::I64Const { value });
550                }
551                0x43 => {
552                    // f32.const
553                    let value = reader.read_f32()?;
554                    instructions.push(crate::program::WasiInstruction::F32Const { value });
555                }
556                0x44 => {
557                    // f64.const
558                    let value = reader.read_f64()?;
559                    instructions.push(crate::program::WasiInstruction::F64Const { value });
560                }
561                0x0B => {
562                    // end
563                    instructions.push(crate::program::WasiInstruction::End);
564                    break;
565                }
566                _ => {
567                    return Err(GaiaError::invalid_data(&format!("Unsupported opcode in init expression: 0x{:02X}", opcode)));
568                }
569            }
570        }
571
572        Ok(instructions)
573    }
574
575    fn read_export_section(
576        &self,
577        reader: &mut BinaryReader<R, LittleEndian>,
578        program: &mut crate::program::WasiProgram,
579    ) -> Result<(), GaiaError> {
580        let count = read_u32_leb128(reader)?;
581
582        for _ in 0..count {
583            // 读取导出名称
584            let name_len = read_u32_leb128(reader)?;
585            let mut name_bytes = vec![0u8; name_len as usize];
586            reader.read_exact(&mut name_bytes)?;
587            let name = String::from_utf8_lossy(&name_bytes).to_string();
588
589            // 读取导出类型和索引
590            let kind = reader.read_u8()?;
591            let index = read_u32_leb128(reader)?;
592
593            let export_type = match kind {
594                0x00 => crate::program::WasmExportType::Function { function_index: index },
595                0x01 => crate::program::WasmExportType::Table { table_index: index },
596                0x02 => crate::program::WasmExportType::Memory { memory_index: index },
597                0x03 => crate::program::WasmExportType::Global { global_index: index },
598                _ => return Err(GaiaError::invalid_data(&format!("Unknown export kind: {}", kind))),
599            };
600
601            program.exports.push(crate::program::WasiExport { name, export_type });
602        }
603
604        Ok(())
605    }
606
607    fn read_code_section(
608        &self,
609        reader: &mut BinaryReader<R, LittleEndian>,
610        program: &mut crate::program::WasiProgram,
611    ) -> Result<(), GaiaError> {
612        let count = read_u32_leb128(reader)?;
613
614        for i in 0..count {
615            // 读取函数体大小
616            let body_size = read_u32_leb128(reader)?;
617            let start_pos = reader.get_position();
618
619            // 读取局部变量
620            let local_count = read_u32_leb128(reader)?;
621            let mut locals = Vec::new();
622            for _ in 0..local_count {
623                let count = read_u32_leb128(reader)?;
624                let value_type = self.read_value_type(reader)?;
625                locals.push(crate::program::WasmLocal { count, value_type });
626            }
627
628            // For now, just skip the function body
629            // In a full implementation, you would parse the instructions here
630            let remaining_size = body_size - (reader.get_position() - start_pos) as u32;
631            let mut body_bytes = vec![0u8; remaining_size as usize];
632            reader.read_exact(&mut body_bytes)?;
633
634            // Update the function with locals (body remains empty for now)
635            program.functions[i as usize].locals = locals;
636
637            // 解析指令
638            let mut body_reader = BinaryReader::new(std::io::Cursor::new(body_bytes));
639            program.functions[i as usize].body = self.read_instructions(&mut body_reader)?;
640        }
641
642        Ok(())
643    }
644
645    fn read_instructions<RR: Read + Seek>(
646        &self,
647        reader: &mut BinaryReader<RR, LittleEndian>,
648    ) -> Result<Vec<crate::program::WasiInstruction>, GaiaError> {
649        let mut instructions = Vec::new();
650        while let Ok(opcode) = reader.read_u8() {
651            match opcode {
652                0x00 => instructions.push(crate::program::WasiInstruction::Unreachable),
653                0x01 => instructions.push(crate::program::WasiInstruction::Nop),
654                0x02 => {
655                    let _block_type = reader.read_u8()?; // Simplified
656                    instructions.push(crate::program::WasiInstruction::Block { block_type: None });
657                }
658                0x03 => {
659                    let _block_type = reader.read_u8()?; // Simplified
660                    instructions.push(crate::program::WasiInstruction::Loop { block_type: None });
661                }
662                0x04 => {
663                    let _block_type = reader.read_u8()?; // Simplified
664                    instructions.push(crate::program::WasiInstruction::If { block_type: None });
665                }
666                0x05 => instructions.push(crate::program::WasiInstruction::Else),
667                0x0B => {
668                    instructions.push(crate::program::WasiInstruction::End);
669                    // 在 Wasm 中,函数结束由 body_size 控制,但指令流通常以 0x0B 结尾
670                }
671                0x0C => {
672                    let label_index = read_u32_leb128(reader)?;
673                    instructions.push(crate::program::WasiInstruction::Br { label_index });
674                }
675                0x0D => {
676                    let label_index = read_u32_leb128(reader)?;
677                    instructions.push(crate::program::WasiInstruction::BrIf { label_index });
678                }
679                0x0F => instructions.push(crate::program::WasiInstruction::Return),
680                0x10 => {
681                    let function_index = read_u32_leb128(reader)?;
682                    instructions.push(crate::program::WasiInstruction::Call { function_index });
683                }
684                0x1A => instructions.push(crate::program::WasiInstruction::Drop),
685                0x1B => instructions.push(crate::program::WasiInstruction::Select),
686                0x20 => {
687                    let local_index = read_u32_leb128(reader)?;
688                    instructions.push(crate::program::WasiInstruction::LocalGet { local_index });
689                }
690                0x21 => {
691                    let local_index = read_u32_leb128(reader)?;
692                    instructions.push(crate::program::WasiInstruction::LocalSet { local_index });
693                }
694                0x41 => {
695                    let value = read_i32_leb128(reader)?;
696                    instructions.push(crate::program::WasiInstruction::I32Const { value });
697                }
698                0x42 => {
699                    let value = read_i64_leb128(reader)?;
700                    instructions.push(crate::program::WasiInstruction::I64Const { value });
701                }
702                0x6A => instructions.push(crate::program::WasiInstruction::I32Add),
703                0x6B => instructions.push(crate::program::WasiInstruction::I32Sub),
704                0x6C => instructions.push(crate::program::WasiInstruction::I32Mul),
705                0x45 => instructions.push(crate::program::WasiInstruction::I32Eqz),
706                0x46 => instructions.push(crate::program::WasiInstruction::I32Eq),
707                0x47 => instructions.push(crate::program::WasiInstruction::I32Ne),
708                0x48 => instructions.push(crate::program::WasiInstruction::I32LtS),
709                0x49 => instructions.push(crate::program::WasiInstruction::I32LtU),
710                0x4A => instructions.push(crate::program::WasiInstruction::I32GtS),
711                0x4B => instructions.push(crate::program::WasiInstruction::I32GtU),
712                0x4C => instructions.push(crate::program::WasiInstruction::I32LeS),
713                0x4D => instructions.push(crate::program::WasiInstruction::I32LeU),
714                0x4E => instructions.push(crate::program::WasiInstruction::I32GeS),
715                0x4F => instructions.push(crate::program::WasiInstruction::I32GeU),
716
717                // WASIp3 扩展指令 (0x5F prefix)
718                0x5F => {
719                    let sub_opcode = reader.read_u8()?;
720                    match sub_opcode {
721                        0x00 => instructions.push(crate::program::WasiInstruction::TaskBackpressure),
722                        0x01 => instructions.push(crate::program::WasiInstruction::TaskReturn),
723                        0x02 => instructions.push(crate::program::WasiInstruction::TaskWait),
724                        0x03 => instructions.push(crate::program::WasiInstruction::TaskPoll),
725                        0x04 => instructions.push(crate::program::WasiInstruction::TaskYield),
726                        0x05 => instructions.push(crate::program::WasiInstruction::ErrorContextNew),
727                        0x06 => instructions.push(crate::program::WasiInstruction::ErrorContextDebugMessage),
728                        _ => {
729                            return Err(GaiaError::invalid_data(&format!("Unknown sub-opcode for 0x5F: 0x{:02X}", sub_opcode)))
730                        }
731                    }
732                }
733                _ => {
734                    // 对于未知的指令,我们可以选择跳过或者报错
735                    // 这里为了简单起见,我们只解析已知的
736                }
737            }
738        }
739        Ok(instructions)
740    }
741}