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 }); }
public WasmDisassembler(EndianImageReader rdr) { this.rdr = new WasmImageReader(new MemoryArea(rdr.Address, rdr.Bytes)) { Offset = rdr.Offset }; }
private Section?LoadGlobalSection(WasmImageReader rdr) { if (!rdr.TryReadVarUInt32(out uint count)) { return(null); } var globals = new List <GlobalEntry>(); for (int i = 0; i < count; ++i) { var global_type = ReadGlobalType(rdr); if (global_type == null) { return(null); } var expr = LoadInitExpr(rdr); globals.Add(new GlobalEntry { Type = global_type.Value, InitExpr = expr, }); } return(new GlobalSection { Globals = globals }); }
private DataType?ReadValueType(WasmImageReader rdr) { if (!rdr.TryReadVarInt7(out sbyte ty)) { return(null); } switch (ty) { case -0x01: return(PrimitiveType.Word32); // i32 case -0x02: return(PrimitiveType.Word64); // i64 case -0x03: return(PrimitiveType.Real32); // f32 case -0x04: return(PrimitiveType.Real64); // f64 case -0x10: return(new TypeReference("anyfunc", new StructureType("anyfunc", 4))); // anyfunc case -0x20: throw new NotImplementedException(); // func case -0x40: throw new NotImplementedException(); // pseudo type for representing an empty block_type default: throw new NotImplementedException(); } }
public WasmDisassembler(WasmArchitecture arch, EndianImageReader rdr) { this.arch = arch; this.addr = rdr.Address; this.rdr = new WasmImageReader(new MemoryArea(rdr.Address, rdr.Bytes)) { Offset = rdr.Offset }; }
private (DataType, bool)? ReadGlobalType(WasmImageReader rdr) { var dt = this.ReadValueType(rdr); if (!rdr.TryReadByte(out byte b)) { return(null); } return(dt !, b != 0); }
private FunctionType?LoadFuncType(WasmImageReader rdr) { byte form; // varint7 the value for the func type constructor as defined above uint param_count; // varuint32 the number of parameters to the function byte return_count; // varuint1 the number of results from the function Identifier?ret = null; // value_type ? the result type of the function(if return_count is 1) if (!rdr.TryReadVarUInt7(out form)) { return(null); } if (!rdr.TryReadVarUInt32(out param_count)) { return(null); } var args = new List <Identifier>(); int cbOffset = 0; for (int i = 0; i < param_count; ++i) { var dt = ReadValueType(rdr); if (dt == null) { return(null); } args.Add(new Identifier( "arg" + i, dt, new StackArgumentStorage(cbOffset, dt))); cbOffset += dt.Size; } if (!rdr.TryReadVarUInt7(out return_count)) { return(null); } if (return_count == 1) { var dt = ReadValueType(rdr); if (dt is null) { return(null); } ret = new Identifier( "", dt, new StackArgumentStorage(0, dt)); } return(new FunctionType( ret !, args.ToArray())); }
public WasmImageReader LoadHeader() { var rdr = new WasmImageReader(RawImage); if (!rdr.TryReadLeUInt32(out uint magic)) { throw new BadImageFormatException(); } if (!rdr.TryReadLeUInt32(out uint version)) { throw new BadImageFormatException(); } return(rdr); }
private List <Section> LoadSections(WasmImageReader rdr) { var sections = new List <Section>(); for (;;) { var s = LoadSection(rdr); if (s == null) { break; } sections.Add(s); } return(sections); }
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?LoadFunctionSection(WasmImageReader rdr) { if (!rdr.TryReadVarUInt32(out uint count)) { return(null); } var decls = new List <uint>(); for (int i = 0; i < count; ++i) { if (!rdr.TryReadVarUInt32(out uint decl)) { return(null); } decls.Add(decl); } return(new FunctionSection { Declarations = decls }); }
private (uint, uint)? ReadResizableLimits(WasmImageReader rdr) { if (!rdr.TryReadVarUInt32(out uint flags)) { return(null); } if (!rdr.TryReadVarUInt32(out uint init)) { return(null); } uint max = 0; if ((flags & 1) != 0) { if (!rdr.TryReadVarUInt32(out max)) { return(null); } } return(init, max); }
private Section?LoadElementSection(WasmImageReader rdr) { if (!rdr.TryReadVarUInt32(out uint count)) { return(null); } var elementSegs = new List <ElementSegment>(); for (int i = 0; i < count; ++i) { if (!rdr.TryReadVarUInt32(out uint table_index)) { return(null); } var offset = LoadInitExpr(rdr); if (!rdr.TryReadVarUInt32(out uint cElems)) { return(null); } var elements = new List <uint>(); for (int j = 0; j < cElems; ++j) { if (!rdr.TryReadVarUInt32(out uint elem)) { return(null); } elements.Add(elem); } elementSegs.Add(new ElementSegment { TableIndex = table_index, Offset = offset, Elements = elements, }); } return(new ElementSection { Segments = elementSegs }); }
private Section?LoadCodeSection(WasmImageReader rdr) { if (!rdr.TryReadVarUInt32(out uint count)) { return(null); } var funcBodies = new List <FunctionDefinition>(); for (int i = 0; i < count; ++i) { var fd = LoadFunctionDefinition(rdr); if (fd == null) { return(null); } funcBodies.Add(fd); } return(new CodeSection { Functions = funcBodies, }); }
private Section?LoadMemorySection(WasmImageReader rdr) { if (!rdr.TryReadVarUInt32(out uint count)) { return(null); } var mems = new List <Memory>(); for (int i = 0; i < count; ++i) { if (!rdr.TryReadVarUInt32(out uint flags)) { return(null); } if (!rdr.TryReadVarUInt32(out uint init)) { return(null); } uint max = 0; if ((flags & 1) != 0) { if (!rdr.TryReadVarUInt32(out max)) { return(null); } } var mem = new Memory { Flags = flags, Initial = init, Maximum = max, }; mems.Add(mem); } return(new MemorySection { Memories = mems, }); }
private Section?LoadTableSection(WasmImageReader rdr) { if (!rdr.TryReadVarUInt32(out uint count)) { return(null); } var tables = new List <TableType>(); for (int i = 0; i < count; ++i) { TableType?tt = ReadTableType(rdr); if (tt == null) { return(null); } tables.Add(tt); } return(new TableSection { Tables = tables }); }
// The type section declares all function signatures that will be used in the module. private Section?LoadTypeSection(WasmImageReader rdr) { if (!rdr.TryReadVarUInt32(out uint count)) { return(null); } var types = new List <FunctionType>(); for (int i = 0; i < count; ++i) { var ft = LoadFuncType(rdr); if (ft is null) { return(null); } types.Add(ft); } return(new TypeSection { Types = types, }); }
private TableType?ReadTableType(WasmImageReader rdr) { var dt = ReadValueType(rdr); if (dt == null) { return(null); } var tpl = ReadResizableLimits(rdr); if (tpl == null) { return(null); } return(new TableType { EntryType = dt, Initial = tpl.Value.Item1, Maximum = tpl.Value.Item2, }); }
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(); } }
private uint LoadInitExpr(WasmImageReader rdr) { var eval = new WasmEvaluator(rdr); return(Convert.ToUInt32(eval.Run())); }
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 WasmEvaluator(WasmImageReader rdr) { this.rdr = rdr; this.stack = new Stack <object>(); }
private Section LoadStartSection(WasmImageReader rdr) { throw new NotImplementedException(); }