public FunctionBody(BinaryReader reader) { // Bit of a hack, but we use positions in this method, so we need to ensure it works if (!reader.BaseStream.CanSeek) { throw new NotSupportedException("Stream passed does not support seeking."); } uint body_size = LEB128.ReadUInt32(reader); var before_pos = reader.BaseStream.Position; uint local_count = LEB128.ReadUInt32(reader); if (local_count > int.MaxValue) { throw new NotImplementedException($"Count larger than {int.MaxValue} bytes not supported."); } locals = new LocalEntry[local_count]; for (uint i = 0; i < local_count; i++) { locals[i] = new LocalEntry(reader); } var after_pos = reader.BaseStream.Position; code = reader.ReadBytes((int)(body_size - (after_pos - before_pos))); if (code[code.Length - 1] != (byte)WebAssemblyOpcode.END) { throw new Exception($"File is invalid. Expected byte {WebAssemblyOpcode.END}, received {code[code.Length-1]}."); } }
public DataSegment(BinaryReader reader) { memory_index = LEB128.ReadUInt32(reader); offset = new InitExpr(reader); uint count = LEB128.ReadUInt32(reader); if (count > int.MaxValue) { throw new NotImplementedException($"Count larger than {int.MaxValue} bytes not supported."); } data = reader.ReadBytes((int)count); }
public LocalEntry(BinaryReader reader) { count = LEB128.ReadUInt32(reader); var tmp_type = reader.ReadByte(); if (!Enum.IsDefined(typeof(WebAssemblyType), tmp_type)) { throw new Exception($"File is invalid. Expected WebAssemblyType, received '{tmp_type}'."); } type = (WebAssemblyType)tmp_type; }
public ElementSegment(BinaryReader reader) { table_index = LEB128.ReadUInt32(reader); offset = new InitExpr(reader); uint num_elem = LEB128.ReadUInt32(reader); function_index = new uint[num_elem]; for (uint i = 0; i < num_elem; i++) { function_index[i] = LEB128.ReadUInt32(reader); } }
public ImportEntry(BinaryReader reader) { uint module_len = LEB128.ReadUInt32(reader); if (module_len > int.MaxValue) { throw new NotImplementedException($"String longer than {int.MaxValue} bytes not supported."); } module_str = Encoding.UTF8.GetString(reader.ReadBytes((int)module_len)); uint field_len = LEB128.ReadUInt32(reader); if (field_len > int.MaxValue) { throw new NotImplementedException($"String longer than {int.MaxValue} bytes not supported."); } field_str = Encoding.UTF8.GetString(reader.ReadBytes((int)field_len)); byte tmp_kind = reader.ReadByte(); if (!Enum.IsDefined(typeof(WebAssemblyExternalKind), tmp_kind)) { throw new Exception($"File is invalid. Expected 0, 1, 2, or 3, received '{tmp_kind}'."); } kind = (WebAssemblyExternalKind)tmp_kind; switch (kind) { case WebAssemblyExternalKind.Function: type = LEB128.ReadUInt32(reader); break; case WebAssemblyExternalKind.Table: var table_tmp = new TableType(reader); type = table_tmp; break; case WebAssemblyExternalKind.Memory: var memory_tmp = new MemoryType(reader); type = memory_tmp; break; case WebAssemblyExternalKind.Global: var global_tmp = new GlobalType(reader); type = global_tmp; break; } }
public DataSection(BinaryReader reader) : base(reader) { uint count = LEB128.ReadUInt32(reader); if (count > int.MaxValue) { throw new NotImplementedException($"Count larger than {int.MaxValue} bytes not supported."); } entries = new DataSegment[count]; for (uint i = 0; i < count; i++) { entries[i] = new DataSegment(reader); } }
public GlobalSection(BinaryReader reader) : base(reader) { uint count = LEB128.ReadUInt32(reader); if (count > int.MaxValue) { throw new NotImplementedException($"Count larger than {int.MaxValue} bytes not supported."); } globals = new GlobalVariable[count]; for (uint i = 0; i < count; i++) { globals[i] = new GlobalVariable(reader); } }
public CodeSection(BinaryReader reader) : base(reader) { uint count = LEB128.ReadUInt32(reader); if (count > int.MaxValue) { throw new NotImplementedException($"Count larger than {int.MaxValue} bytes not supported."); } bodies = new FunctionBody[count]; for (uint i = 0; i < count; i++) { bodies[i] = new FunctionBody(reader); } }
public CustomSection(BinaryReader reader) : base(reader) { uint name_len = LEB128.ReadUInt32(reader); name = Encoding.UTF8.GetString(reader.ReadBytes((int)name_len)); uint payload_size = payload_len - (LEB128.SizeOf(name_len) + name_len); if (payload_size > int.MaxValue) { throw new NotImplementedException($"Payload longer than {int.MaxValue} bytes not supported."); } payload_data = reader.ReadBytes((int)payload_size); }
public void ReadTest(MemoryStream stream) { BinaryReader reader = new BinaryReader(stream); Assert.AreEqual(LEB128.ReadUInt32(reader), 0xFF00FF00u); Assert.AreEqual(LEB128.ReadUInt32(reader), 0xAABBAAu); Assert.AreEqual(LEB128.ReadUInt32(reader), 0xCCu); Assert.AreEqual(LEB128.ReadUInt7(reader), 0x11u); Assert.AreEqual(LEB128.ReadUInt7(reader), 0x7Fu); Assert.AreEqual(LEB128.ReadInt32(reader), 0x7F00FF00); Assert.AreEqual(LEB128.ReadInt32(reader), 0xAABBAA); Assert.AreEqual(LEB128.ReadInt32(reader), 0xCC); Assert.AreEqual(LEB128.ReadInt32(reader), -1); Assert.AreEqual(LEB128.ReadInt7(reader), 0x11); Assert.AreEqual(LEB128.ReadInt7(reader), -1); }
public ResizeLimit(BinaryReader reader) { byte flags = LEB128.ReadUInt7(reader); if (flags != 0 && flags != 1) { throw new Exception($"File is invalid. Expected 0 or 1, received '{flags}'."); } initial = LEB128.ReadUInt32(reader); if (flags != 0) { maximum = LEB128.ReadUInt32(reader); if (maximum < initial) { throw new Exception($"File is invalid. Initial memory size greater than maximum."); } } }
public FuncType(BinaryReader reader) { int form = LEB128.ReadInt7(reader); if (form != (int)WebAssemblyType.func) { throw new Exception($"File is invalid. Expected byte '{WebAssemblyType.func}', received '{form}'."); } uint param_count = LEB128.ReadUInt32(reader); if (param_count > int.MaxValue) { throw new NotImplementedException($"Count larger than {int.MaxValue} bytes not supported."); } param_types = new WebAssemblyType[param_count]; for (uint i = 0; i < param_count; i++) { param_types[i] = (WebAssemblyType)LEB128.ReadInt7(reader); if (!WebAssemblyHelper.IsValueType(param_types[i])) { throw new Exception($"File is invalid. Expected valid value type, received '{param_types[i]}'."); } } int return_count = LEB128.ReadInt7(reader); if (return_count != 0 && return_count != 1) { throw new Exception($"File is invalid. Expected byte 0 or 1, received {return_count}."); } if (return_count == 1) { return_type = (WebAssemblyType)LEB128.ReadInt7(reader); if (!WebAssemblyHelper.IsValueType((WebAssemblyType)return_type)) { throw new Exception($"File is invalid. Expected valid value type, received '{return_type}'."); } } }
public ExportEntry(BinaryReader reader) { uint field_len = LEB128.ReadUInt32(reader); if (field_len > int.MaxValue) { throw new NotImplementedException($"String longer than {int.MaxValue} bytes not supported."); } field_str = Encoding.UTF8.GetString(reader.ReadBytes((int)field_len)); var tmp_kind = reader.ReadByte(); if (!Enum.IsDefined(typeof(WebAssemblyExternalKind), tmp_kind)) { throw new Exception($"File is invalid. Expected byte 0, 1, 2, or 3, received '{tmp_kind}'."); } kind = (WebAssemblyExternalKind)tmp_kind; index = LEB128.ReadUInt32(reader); }
public StartSection(BinaryReader reader) : base(reader) { index = LEB128.ReadUInt32(reader); }