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