private Section?LoadExportSection(WasmImageReader rdr) { if (!rdr.TryReadVarUInt32(out uint count)) { return(null); } var exports = new List <ExportEntry>(); for (int i = 0; i < count; ++i) { if (!rdr.TryReadVarUInt32(out uint len)) { return(null); } var field = Encoding.UTF8.GetString(rdr.ReadBytes(len)); if (!rdr.TryReadByte(out byte kind)) { return(null); } if (!rdr.TryReadVarUInt32(out uint index)) { return(null); } exports.Add(new ExportEntry { Field = field, Kind = kind, Index = index, }); } return(new ExportSection { ExportEntries = exports }); }
private Section?LoadDataSection(WasmImageReader rdr) { if (!rdr.TryReadVarUInt32(out uint count)) { return(null); } var segments = new List <DataSegment>(); for (int i = 0; i < count; ++i) { /* * index varuint32 the linear memory index (0 in the MVP) * offset init_expr an i32 initializer expression that computes the offset at which to place the data * size varuint32 size of data (in bytes) * data bytes sequence of size bytes */ if (!rdr.TryReadVarUInt32(out uint index)) { return(null); } var offset = LoadInitExpr(rdr); if (!rdr.TryReadVarUInt32(out uint size)) { return(null); } var bytes = rdr.ReadBytes(size); if (bytes == null) { return(null); } segments.Add(new DataSegment { MemoryIndex = index, Offset = offset, Bytes = bytes, }); } return(new DataSection { Segments = segments }); }
private FunctionDefinition?LoadFunctionDefinition(WasmImageReader rdr) { if (!rdr.TryReadVarUInt32(out uint len)) { return(null); } var start = (int)rdr.Offset; var end = start + (int)len; if (!rdr.TryReadVarUInt32(out uint cEntries)) { return(null); } var locals = new List <LocalVariable>(); for (int i = 0; i < cEntries; ++i) { if (!rdr.TryReadVarUInt32(out uint n)) { return(null); } var dt = ReadValueType(rdr); if (dt == null) { return(null); } locals.AddRange(Enumerable.Range(0, (int)n).Select(nn => new LocalVariable { DataType = dt })); } len -= (uint)(rdr.Offset - start); var codeBytes = rdr.ReadBytes(len); return(new FunctionDefinition { Start = start, End = end, Locals = locals.ToArray(), ByteCode = codeBytes }); }
private Section?LoadImportSection(WasmImageReader rdr) { if (!rdr.TryReadVarUInt32(out uint count)) { return(null); } var imps = new List <Import>(); for (uint i = 0; i < count; ++i) { if (!rdr.TryReadVarUInt32(out uint len)) { return(null); } string module = Encoding.UTF8.GetString(rdr.ReadBytes(len)); if (!rdr.TryReadVarUInt32(out len)) { return(null); } string field = Encoding.UTF8.GetString(rdr.ReadBytes(len)); if (!rdr.TryReadByte(out byte external_kind)) { return(null); } switch (external_kind) { case 0: uint function_index; if (!rdr.TryReadVarUInt32(out function_index)) { return(null); } imps.Add(new Import { Type = SymbolType.ExternalProcedure, Module = module, Field = field, Index = function_index, }); break; case 1: var table = this.ReadTableType(rdr); if (table == null) { return(null); } imps.Add(new Import { Type = SymbolType.Table, Module = module, Field = field, TableType = table, }); break; case 2: var memory_type = ReadResizableLimits(rdr); if (memory_type == null) { return(null); } imps.Add(new Import { Type = SymbolType.AddressSpace, Module = module, Field = field, MemoryType = memory_type.Value, }); break; case 3: var global_type = ReadGlobalType(rdr); if (global_type == null) { return(null); } imps.Add(new Import { Type = SymbolType.Data, Module = module, Field = field, GlobalType = global_type.Value, }); break; default: throw new NotImplementedException(); } /* * * 0 indicating a Function import or definition * 1 indicating a Table import or definition * 2 indicating a Memory import or definition * 3 indicating a Global import or definition * */ } return(new ImportSection { Imports = imps, }); }
public Section?LoadSection(WasmImageReader rdr) { if (!rdr.TryReadVarUInt7(out byte bType)) { return(null); // no more data, return. } var type = (WasmSection)bType; if (!rdr.TryReadVarUInt32(out uint payload_len)) { throw new BadImageFormatException(); } string name; if (type == WasmSection.Custom) { var offset = rdr.Offset; // Custom sections' names are part of the payload. if (!rdr.TryReadVarUInt32(out uint name_len) || name_len == 0) { throw new NotImplementedException(); } name = Encoding.UTF8.GetString(rdr.ReadBytes(name_len)); payload_len -= (uint)(rdr.Offset - offset); } else { name = type.ToString(); } byte[] bytes; if (payload_len > 0) { bytes = rdr.ReadBytes(payload_len); } else { bytes = new byte[0]; } var rdr2 = new WasmImageReader(bytes); switch (type) { case WasmSection.Custom: return(LoadCustomSection(name, bytes)); // custom section case WasmSection.Type: return(LoadTypeSection(rdr2)); // Function signature declarations case WasmSection.Import: return(LoadImportSection(rdr2)); // Import declarations case WasmSection.Function: return(LoadFunctionSection(rdr2)); // Function declarations case WasmSection.Table: return(LoadTableSection(rdr2)); // Indirect function table and other tables case WasmSection.Memory: return(LoadMemorySection(rdr2)); // Memory attributes case WasmSection.Global: return(LoadGlobalSection(rdr2)); // Global declarations case WasmSection.Export: return(LoadExportSection(rdr2)); // Exports case WasmSection.Start: return(LoadStartSection(rdr2)); // Start function declaration case WasmSection.Element: return(LoadElementSection(rdr2)); // Elements section case WasmSection.Code: return(LoadCodeSection(rdr2)); // Function bodies (code) case WasmSection.Data: return(LoadDataSection(rdr2)); // Data segments default: throw new NotSupportedException(); } }