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 gaia_binary::{BinaryReader, Fixed, LittleEndian};
8use gaia_types::{GaiaDiagnostics, GaiaError};
9use std::{
10    cell::{OnceCell, RefCell},
11    io::{Read, Seek},
12};
13
14/// WASM LEB128 reader helper
15pub fn read_u32_leb128<R: Read + Seek, F: gaia_binary::BinaryFormat>(reader: &mut BinaryReader<R, F>) -> std::io::Result<u32> {
16    let mut result = 0u32;
17    let mut shift = 0;
18    loop {
19        let b = reader.read_u8().map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string()))?;
20        result |= ((b & 0x7F) as u32) << shift;
21        if b & 0x80 == 0 {
22            break;
23        }
24        shift += 7;
25        if shift >= 32 {
26            return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "LEB128 value too large for u32"));
27        }
28    }
29    Ok(result)
30}
31
32fn read_i32_leb128<R: Read + Seek, F: gaia_binary::BinaryFormat>(reader: &mut BinaryReader<R, F>) -> std::io::Result<i32> {
33    let mut result = 0i32;
34    let mut shift = 0;
35    let mut byte;
36    loop {
37        byte = reader.read_u8().map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string()))?;
38        result |= ((byte & 0x7F) as i32) << shift;
39        shift += 7;
40        if byte & 0x80 == 0 {
41            break;
42        }
43    }
44    if shift < 32 && (byte & 0x40) != 0 {
45        result |= !0 << shift;
46    }
47    Ok(result)
48}
49
50fn read_i64_leb128<R: Read + Seek, F: gaia_binary::BinaryFormat>(reader: &mut BinaryReader<R, F>) -> std::io::Result<i64> {
51    let mut result = 0i64;
52    let mut shift = 0;
53    let mut byte;
54    loop {
55        byte = reader.read_u8().map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string()))?;
56        result |= ((byte & 0x7F) as i64) << shift;
57        shift += 7;
58        if byte & 0x80 == 0 {
59            break;
60        }
61    }
62    if shift < 64 && (byte & 0x40) != 0 {
63        result |= !0 << shift;
64    }
65    Ok(result)
66}
67
68/// WASM 文件读取器
69pub struct WasmReader<'config, R: Read + Seek> {
70    config: &'config WasmReadConfig,
71    reader: RefCell<BinaryReader<R, Fixed<LittleEndian>>>,
72    program: OnceCell<WasiProgram>,
73    view: OnceCell<WasmInfo>,
74}
75
76impl WasmReadConfig {
77    pub fn as_reader<R: Read + Seek>(&self, reader: R) -> WasmReader<'_, R> {
78        WasmReader::new(reader, self)
79    }
80}
81
82impl<'config, R: Read + Seek> WasmReader<'config, R> {
83    pub fn new(reader: R, config: &'config WasmReadConfig) -> Self {
84        Self {
85            reader: RefCell::new(BinaryReader::<R, Fixed<LittleEndian>>::new(reader)),
86            view: Default::default(),
87            program: Default::default(),
88            config: config,
89        }
90    }
91    pub fn finish(mut self) -> GaiaDiagnostics<WasiProgram>
92    where
93        R: Read + Seek,
94    {
95        match self.get_program() {
96            Ok(_) => {
97                let errors = self.reader.borrow_mut().take_errors();
98                GaiaDiagnostics {
99                    result: self.program.take().ok_or(GaiaError::custom_error("unreachable")),
100                    diagnostics: errors,
101                }
102            }
103            Err(e) => {
104                let errors = self.reader.borrow_mut().take_errors();
105                GaiaDiagnostics { result: Err(e), diagnostics: errors }
106            }
107        }
108    }
109}
110
111impl<'config, R: Read + Seek> WasmReader<'config, R> {
112    pub fn get_program(&self) -> Result<&WasiProgram, GaiaError> {
113        self.program.get_or_try_init(|| self.read_program())
114    }
115    fn read_program(&self) -> Result<WasiProgram, GaiaError> {
116        let mut reader = self.reader.borrow_mut();
117
118        // 重新定位到文件开头
119        reader.seek(std::io::SeekFrom::Start(0)).map_err(|e| GaiaError::custom_error(format!("I/O error: {:?}", e)))?;
120
121        // 验证 WASM 文件头
122        self.validate_wasm_header(&mut reader)?;
123
124        // 创建核心模块程序
125        let mut program = crate::program::WasiProgram::new_core_module();
126
127        // 解析各个段
128        self.parse_sections(&mut reader, &mut program)?;
129
130        Ok(program)
131    }
132
133    fn validate_wasm_header(&self, reader: &mut BinaryReader<R, Fixed<LittleEndian>>) -> Result<(), GaiaError> {
134        // 读取并验证 WASM 文件头
135        let magic = reader.read_u32().map_err(|e| GaiaError::custom_error(format!("I/O error: {:?}", e)))?;
136        if magic != 0x6D736100 {
137            // "\0asm" in little-endian
138            return Err(GaiaError::invalid_data("Invalid WASM file magic number"));
139        }
140
141        let version = reader.read_u32().map_err(|e| GaiaError::custom_error(format!("I/O error: {:?}", e)))?;
142        if version != 1 {
143            return Err(GaiaError::invalid_data(&format!("Unsupported WASM version: {}", version)));
144        }
145
146        Ok(())
147    }
148
149    fn parse_sections(
150        &self,
151        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
152        program: &mut crate::program::WasiProgram,
153    ) -> Result<(), GaiaError> {
154        while let Ok(section_id) = reader.read_u8() {
155            let section_size = read_u32_leb128(reader).map_err(|e| GaiaError::custom_error(format!("I/O error: {:?}", e)))?;
156
157            match section_id {
158                0 => self.read_custom_section(reader, program, section_size)?,
159                1 => self.read_type_section(reader, program)?,
160                2 => self.read_import_section(reader, program)?,
161                3 => self.read_function_section(reader, program)?,
162                4 => self.read_table_section(reader, program)?,
163                5 => self.read_memory_section(reader, program)?,
164                6 => self.read_global_section(reader, program)?,
165                7 => self.read_export_section(reader, program)?,
166                8 => self.read_start_section(reader, program)?,
167                9 => self.skip_section(reader, section_size)?, // Element section
168                10 => self.read_code_section(reader, program)?,
169                11 => self.skip_section(reader, section_size)?, // Data section
170                _ => self.skip_section(reader, section_size)?,  // Unknown section
171            }
172        }
173        Ok(())
174    }
175
176    fn read_custom_section(
177        &self,
178        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
179        program: &mut crate::program::WasiProgram,
180        section_size: u32,
181    ) -> Result<(), GaiaError> {
182        let name_len = read_u32_leb128(reader)?;
183        let mut name_bytes = vec![0u8; name_len as usize];
184        reader.read_exact(&mut name_bytes)?;
185        let name = String::from_utf8_lossy(&name_bytes).to_string();
186
187        // 计算数据长度
188        let mut len = name_len;
189        let mut temp = name_len;
190        while temp > 0 {
191            len += 1;
192            temp >>= 7;
193        }
194        let data_len = section_size - 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, Fixed<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, Fixed<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, Fixed<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, Fixed<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, Fixed<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(
372        &self,
373        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
374    ) -> Result<crate::program::WasmValueType, GaiaError> {
375        let type_byte = reader.read_u8()?;
376        crate::program::WasmValueType::try_from(type_byte)
377    }
378
379    fn read_import_section(
380        &self,
381        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
382        program: &mut crate::program::WasiProgram,
383    ) -> Result<(), GaiaError> {
384        let count = read_u32_leb128(reader)?;
385
386        for _ in 0..count {
387            // 读取模块名
388            let module_len = read_u32_leb128(reader)?;
389            let mut module_bytes = vec![0u8; module_len as usize];
390            reader.read_exact(&mut module_bytes)?;
391            let module = String::from_utf8_lossy(&module_bytes).to_string();
392
393            // 读取字段名
394            let field_len = read_u32_leb128(reader)?;
395            let mut field_bytes = vec![0u8; field_len as usize];
396            reader.read_exact(&mut field_bytes)?;
397            let field = String::from_utf8_lossy(&field_bytes).to_string();
398
399            let import_type = self.read_import_type(reader)?;
400
401            program.imports.push(crate::program::WasiImport { module, field, import_type });
402        }
403
404        Ok(())
405    }
406
407    fn read_import_type(
408        &self,
409        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
410    ) -> Result<crate::program::WasmImportType, GaiaError> {
411        let kind = reader.read_u8()?;
412        match kind {
413            0x00 => {
414                // Function
415                let type_index = read_u32_leb128(reader)?;
416                Ok(crate::program::WasmImportType::Function { type_index })
417            }
418            0x01 => {
419                // Table
420                let table_type = self.read_table_type(reader)?;
421                Ok(crate::program::WasmImportType::Table { table_type })
422            }
423            0x02 => {
424                // Memory
425                let memory_type = self.read_memory_type(reader)?;
426                Ok(crate::program::WasmImportType::Memory { memory_type })
427            }
428            0x03 => {
429                // Global
430                let global_type = self.read_global_type(reader)?;
431                Ok(crate::program::WasmImportType::Global { global_type })
432            }
433            _ => Err(GaiaError::invalid_data(&format!("Unknown import kind: {}", kind))),
434        }
435    }
436
437    fn read_function_section(
438        &self,
439        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
440        program: &mut crate::program::WasiProgram,
441    ) -> Result<(), GaiaError> {
442        let count = read_u32_leb128(reader)?;
443
444        for _ in 0..count {
445            let type_index = read_u32_leb128(reader)?;
446            // 创建空的函数,稍后在 code section 中填充
447            program.functions.push(crate::program::WasiFunction { type_index, locals: Vec::new(), body: Vec::new() });
448        }
449
450        Ok(())
451    }
452
453    fn read_table_section(
454        &self,
455        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
456        program: &mut crate::program::WasiProgram,
457    ) -> Result<(), GaiaError> {
458        let count = read_u32_leb128(reader)?;
459
460        for _ in 0..count {
461            let table_type = self.read_table_type(reader)?;
462            program.tables.push(crate::program::WasiTable { table_type });
463        }
464
465        Ok(())
466    }
467
468    fn read_table_type(
469        &self,
470        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
471    ) -> Result<crate::program::WasmTableType, GaiaError> {
472        let element_type = reader.read_u8()?;
473        let element_type = match element_type {
474            0x70 => crate::program::WasmReferenceType::FuncRef,
475            0x6F => crate::program::WasmReferenceType::ExternRef,
476            _ => return Err(GaiaError::invalid_data(&format!("Unknown reference type: 0x{:02X}", element_type))),
477        };
478
479        let limits = self.read_limits(reader)?;
480
481        Ok(crate::program::WasmTableType { element_type, min: limits.0, max: limits.1 })
482    }
483
484    fn read_memory_section(
485        &self,
486        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
487        program: &mut crate::program::WasiProgram,
488    ) -> Result<(), GaiaError> {
489        let count = read_u32_leb128(reader)?;
490
491        for _ in 0..count {
492            let memory_type = self.read_memory_type(reader)?;
493            program.memories.push(crate::program::WasiMemory { memory_type });
494        }
495
496        Ok(())
497    }
498
499    fn read_memory_type(
500        &self,
501        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
502    ) -> Result<crate::program::WasmMemoryType, GaiaError> {
503        let limits = self.read_limits(reader)?;
504        Ok(crate::program::WasmMemoryType { min: limits.0, max: limits.1 })
505    }
506
507    fn read_limits(&self, reader: &mut BinaryReader<R, Fixed<LittleEndian>>) -> Result<(u32, Option<u32>), GaiaError> {
508        let flags = reader.read_u8()?;
509        let min = read_u32_leb128(reader)?;
510        let max = if flags & 0x01 != 0 { Some(read_u32_leb128(reader)?) } else { None };
511        Ok((min, max))
512    }
513
514    fn read_global_section(
515        &self,
516        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
517        program: &mut crate::program::WasiProgram,
518    ) -> Result<(), GaiaError> {
519        let count = read_u32_leb128(reader)?;
520
521        for _ in 0..count {
522            let global_type = self.read_global_type(reader)?;
523            let init_expr = self.read_init_expr(reader)?;
524            program.globals.push(crate::program::WasiGlobal { global_type, init_expr });
525        }
526
527        Ok(())
528    }
529
530    fn read_global_type(
531        &self,
532        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
533    ) -> Result<crate::program::WasmGlobalType, GaiaError> {
534        let value_type = self.read_value_type(reader)?;
535        let mutability = reader.read_u8()?;
536        let mutable = mutability != 0;
537
538        Ok(crate::program::WasmGlobalType { value_type, mutable })
539    }
540
541    fn read_init_expr(
542        &self,
543        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
544    ) -> Result<Vec<crate::program::WasiInstruction>, GaiaError> {
545        let mut instructions = Vec::new();
546
547        loop {
548            let opcode = reader.read_u8()?;
549            match opcode {
550                0x41 => {
551                    // i32.const
552                    let value = read_i32_leb128(reader)?;
553                    instructions.push(crate::program::WasiInstruction::I32Const { value });
554                }
555                0x42 => {
556                    // i64.const
557                    let value = read_i64_leb128(reader)?;
558                    instructions.push(crate::program::WasiInstruction::I64Const { value });
559                }
560                0x43 => {
561                    // f32.const
562                    let value = reader.read_f32()?;
563                    instructions.push(crate::program::WasiInstruction::F32Const { value });
564                }
565                0x44 => {
566                    // f64.const
567                    let value = reader.read_f64()?;
568                    instructions.push(crate::program::WasiInstruction::F64Const { value });
569                }
570                0x0B => {
571                    // end
572                    instructions.push(crate::program::WasiInstruction::End);
573                    break;
574                }
575                _ => {
576                    return Err(GaiaError::invalid_data(&format!("Unsupported opcode in init expression: 0x{:02X}", opcode)));
577                }
578            }
579        }
580
581        Ok(instructions)
582    }
583
584    fn read_export_section(
585        &self,
586        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
587        program: &mut crate::program::WasiProgram,
588    ) -> Result<(), GaiaError> {
589        let count = read_u32_leb128(reader)?;
590
591        for _ in 0..count {
592            // 读取导出名称
593            let name_len = read_u32_leb128(reader)?;
594            let mut name_bytes = vec![0u8; name_len as usize];
595            reader.read_exact(&mut name_bytes)?;
596            let name = String::from_utf8_lossy(&name_bytes).to_string();
597
598            // 读取导出类型和索引
599            let kind = reader.read_u8()?;
600            let index = read_u32_leb128(reader)?;
601
602            let export_type = match kind {
603                0x00 => crate::program::WasmExportType::Function { function_index: index },
604                0x01 => crate::program::WasmExportType::Table { table_index: index },
605                0x02 => crate::program::WasmExportType::Memory { memory_index: index },
606                0x03 => crate::program::WasmExportType::Global { global_index: index },
607                _ => return Err(GaiaError::invalid_data(&format!("Unknown export kind: {}", kind))),
608            };
609
610            program.exports.push(crate::program::WasiExport { name, export_type });
611        }
612
613        Ok(())
614    }
615
616    fn read_code_section(
617        &self,
618        reader: &mut BinaryReader<R, Fixed<LittleEndian>>,
619        program: &mut crate::program::WasiProgram,
620    ) -> Result<(), GaiaError> {
621        let count = read_u32_leb128(reader)?;
622
623        for i in 0..count {
624            // 读取函数体大小
625            let body_size = read_u32_leb128(reader)?;
626            let start_pos = reader.get_position();
627
628            // 读取局部变量
629            let local_count = read_u32_leb128(reader)?;
630            let mut locals = Vec::new();
631            for _ in 0..local_count {
632                let count = read_u32_leb128(reader)?;
633                let value_type = self.read_value_type(reader)?;
634                locals.push(crate::program::WasmLocal { count, value_type });
635            }
636
637            // For now, just skip the function body
638            // In a full implementation, you would parse the instructions here
639            let remaining_size = body_size - (reader.position() - start_pos) as u32;
640            let mut body_bytes = vec![0u8; remaining_size as usize];
641            reader.read_exact(&mut body_bytes)?;
642
643            // Update the function with locals (body remains empty for now)
644            program.functions[i as usize].locals = locals;
645
646            // 解析指令
647            let mut body_reader = BinaryReader::new(std::io::Cursor::new(body_bytes));
648            program.functions[i as usize].body = self.read_instructions(&mut body_reader)?;
649        }
650
651        Ok(())
652    }
653
654    fn read_instructions<RR: Read + Seek>(
655        &self,
656        reader: &mut BinaryReader<RR, Fixed<LittleEndian>>,
657    ) -> Result<Vec<crate::program::WasiInstruction>, GaiaError> {
658        let mut instructions = Vec::new();
659        while let Ok(opcode) = reader.read_u8() {
660            match opcode {
661                0x00 => instructions.push(crate::program::WasiInstruction::Unreachable),
662                0x01 => instructions.push(crate::program::WasiInstruction::Nop),
663                0x02 => {
664                    let _block_type = reader.read_u8()?; // Simplified
665                    instructions.push(crate::program::WasiInstruction::Block { block_type: None });
666                }
667                0x03 => {
668                    let _block_type = reader.read_u8()?; // Simplified
669                    instructions.push(crate::program::WasiInstruction::Loop { block_type: None });
670                }
671                0x04 => {
672                    let _block_type = reader.read_u8()?; // Simplified
673                    instructions.push(crate::program::WasiInstruction::If { block_type: None });
674                }
675                0x05 => instructions.push(crate::program::WasiInstruction::Else),
676                0x0B => {
677                    instructions.push(crate::program::WasiInstruction::End);
678                    // 在 Wasm 中,函数结束由 body_size 控制,但指令流通常以 0x0B 结尾
679                }
680                0x0C => {
681                    let label_index = read_u32_leb128(reader)?;
682                    instructions.push(crate::program::WasiInstruction::Br { label_index });
683                }
684                0x0D => {
685                    let label_index = read_u32_leb128(reader)?;
686                    instructions.push(crate::program::WasiInstruction::BrIf { label_index });
687                }
688                0x0F => instructions.push(crate::program::WasiInstruction::Return),
689                0x10 => {
690                    let function_index = read_u32_leb128(reader)?;
691                    instructions.push(crate::program::WasiInstruction::Call { function_index });
692                }
693                0x1A => instructions.push(crate::program::WasiInstruction::Drop),
694                0x1B => instructions.push(crate::program::WasiInstruction::Select),
695                0x20 => {
696                    let local_index = read_u32_leb128(reader)?;
697                    instructions.push(crate::program::WasiInstruction::LocalGet { local_index });
698                }
699                0x21 => {
700                    let local_index = read_u32_leb128(reader)?;
701                    instructions.push(crate::program::WasiInstruction::LocalSet { local_index });
702                }
703                0x41 => {
704                    let value = read_i32_leb128(reader)?;
705                    instructions.push(crate::program::WasiInstruction::I32Const { value });
706                }
707                0x42 => {
708                    let value = read_i64_leb128(reader)?;
709                    instructions.push(crate::program::WasiInstruction::I64Const { value });
710                }
711                0x6A => instructions.push(crate::program::WasiInstruction::I32Add),
712                0x6B => instructions.push(crate::program::WasiInstruction::I32Sub),
713                0x6C => instructions.push(crate::program::WasiInstruction::I32Mul),
714                0x45 => instructions.push(crate::program::WasiInstruction::I32Eqz),
715                0x46 => instructions.push(crate::program::WasiInstruction::I32Eq),
716                0x47 => instructions.push(crate::program::WasiInstruction::I32Ne),
717                0x48 => instructions.push(crate::program::WasiInstruction::I32LtS),
718                0x49 => instructions.push(crate::program::WasiInstruction::I32LtU),
719                0x4A => instructions.push(crate::program::WasiInstruction::I32GtS),
720                0x4B => instructions.push(crate::program::WasiInstruction::I32GtU),
721                0x4C => instructions.push(crate::program::WasiInstruction::I32LeS),
722                0x4D => instructions.push(crate::program::WasiInstruction::I32LeU),
723                0x4E => instructions.push(crate::program::WasiInstruction::I32GeS),
724                0x4F => instructions.push(crate::program::WasiInstruction::I32GeU),
725
726                // WASIp3 扩展指令 (0x5F prefix)
727                0x5F => {
728                    let sub_opcode = reader.read_u8()?;
729                    match sub_opcode {
730                        0x00 => instructions.push(crate::program::WasiInstruction::TaskBackpressure),
731                        0x01 => instructions.push(crate::program::WasiInstruction::TaskReturn),
732                        0x02 => instructions.push(crate::program::WasiInstruction::TaskWait),
733                        0x03 => instructions.push(crate::program::WasiInstruction::TaskPoll),
734                        0x04 => instructions.push(crate::program::WasiInstruction::TaskYield),
735                        0x05 => instructions.push(crate::program::WasiInstruction::ErrorContextNew),
736                        0x06 => instructions.push(crate::program::WasiInstruction::ErrorContextDebugMessage),
737                        _ => {
738                            return Err(GaiaError::invalid_data(&format!("Unknown sub-opcode for 0x5F: 0x{:02X}", sub_opcode)))
739                        }
740                    }
741                }
742                _ => {
743                    // 对于未知的指令,我们可以选择跳过或者报错
744                    // 这里为了简单起见,我们只解析已知的
745                }
746            }
747        }
748        Ok(instructions)
749    }
750}