Encodes this module into a WebAssembly binary.
(&mut self)
| 777 | |
| 778 | /// Encodes this module into a WebAssembly binary. |
| 779 | pub fn encode(&mut self) -> Vec<u8> { |
| 780 | // Build the function/export sections of the wasm module in a first pass |
| 781 | // which will assign a final `FuncIndex` to all functions defined in |
| 782 | // `self.funcs`. |
| 783 | let mut funcs = FunctionSection::new(); |
| 784 | let mut exports = ExportSection::new(); |
| 785 | let mut id_to_index = PrimaryMap::<FunctionId, FuncIndex>::new(); |
| 786 | for (id, func) in self.funcs.iter() { |
| 787 | assert!(func.filled_in); |
| 788 | let idx = FuncIndex::from_u32(self.imported_funcs.next_key().as_u32() + id.as_u32()); |
| 789 | let id2 = id_to_index.push(idx); |
| 790 | assert_eq!(id2, id); |
| 791 | |
| 792 | funcs.function(func.ty); |
| 793 | |
| 794 | if let Some(name) = &func.export { |
| 795 | exports.export(name, ExportKind::Func, idx.as_u32()); |
| 796 | } |
| 797 | } |
| 798 | for (idx, name) in &self.exports { |
| 799 | exports.export(name, ExportKind::Func, *idx); |
| 800 | } |
| 801 | |
| 802 | // With all functions numbered the fragments of the body of each |
| 803 | // function can be assigned into one final adapter function. |
| 804 | let mut code = CodeSection::new(); |
| 805 | for (_, func) in self.funcs.iter() { |
| 806 | let mut body = Vec::new(); |
| 807 | |
| 808 | // Encode all locals used for this function |
| 809 | func.locals.len().encode(&mut body); |
| 810 | for (count, ty) in func.locals.iter() { |
| 811 | count.encode(&mut body); |
| 812 | ty.encode(&mut body); |
| 813 | } |
| 814 | |
| 815 | // Then encode each "chunk" of a body which may have optional traps |
| 816 | // specified within it. Traps get offset by the current length of |
| 817 | // the body and otherwise our `Call` instructions are "relocated" |
| 818 | // here to the final function index. |
| 819 | for chunk in func.body.iter() { |
| 820 | match chunk { |
| 821 | Body::Raw(code) => { |
| 822 | body.extend_from_slice(code); |
| 823 | } |
| 824 | Body::Call(id) => { |
| 825 | Instruction::Call(id_to_index[*id].as_u32()).encode(&mut body); |
| 826 | } |
| 827 | Body::RefFunc(id) => { |
| 828 | Instruction::RefFunc(id_to_index[*id].as_u32()).encode(&mut body); |
| 829 | } |
| 830 | } |
| 831 | } |
| 832 | code.raw(&body); |
| 833 | } |
| 834 | |
| 835 | let mut result = wasm_encoder::Module::new(); |
| 836 | result.section(&self.core_types.section); |
no test coverage detected