/// <summary> /// Reads the child instructions of a WebAssembly block from the given reader. /// </summary> /// <param name="blockType">The type of value returned by the resulting block.</param> /// <param name="reader">The WebAssembly file reader.</param> /// <returns>A WebAssembly block instruction.</returns> public static IfElseInstruction ReadBlockContents(WasmType blockType, BinaryWasmReader reader) { var ifBranch = new List <Instruction>(); List <Instruction> elseBranch = null; while (true) { byte opCode = reader.ReadByte(); if (opCode == Operators.EndOpCode) { return(new IfElseInstruction(blockType, ifBranch, elseBranch)); } else if (opCode == Operators.ElseOpCode) { if (elseBranch != null) { throw new WasmException("More than one 'else' opcode in an 'if' instruction"); } elseBranch = new List <Instruction>(); } else { var op = Operators.GetOperatorByOpCode(opCode); (elseBranch == null ? ifBranch : elseBranch).Add(op.ReadImmediates(reader)); } } }
/// <summary> /// Reads a local entry from the given WebAssembly file reader. /// </summary> /// <param name="Reader">The WebAssembly file reader.</param> /// <returns>A local entry.</returns> public static LocalEntry ReadFrom(BinaryWasmReader Reader) { var count = Reader.ReadVarUInt32(); var type = Reader.ReadWasmValueType(); return(new LocalEntry(type, count)); }
/// <summary> /// Reads a function body from the given WebAssembly file reader. /// </summary> /// <param name="Reader">The WebAssembly file reader to use.</param> /// <returns>A function body.</returns> public static FunctionBody ReadFrom(BinaryWasmReader Reader) { // Read the length of the function body definition. uint funcBodyLength = Reader.ReadVarUInt32(); // Save the function body's start position. long startPos = Reader.Position; // Read the number of local entries. uint localEntryCount = Reader.ReadVarUInt32(); // Read local entries. var localEntries = new List <LocalEntry>((int)localEntryCount); for (uint i = 0; i < localEntryCount; i++) { localEntries.Add(LocalEntry.ReadFrom(Reader)); } // Read the function's body block. var body = Operators.Block.ReadBlockContents(WasmType.Empty, Reader); // Skip any remaining bytes. var extraPayload = Reader.ReadRemainingPayload(startPos, funcBodyLength); return(new FunctionBody(localEntries, body.Contents, extraPayload)); }
/// <summary> /// Reads a single function type from the given reader. /// </summary> /// <returns>The function type.</returns> public static FunctionType ReadFrom(BinaryWasmReader reader) { WasmType form = (WasmType)reader.ReadWasmType(); if (form != WasmType.Func) { throw new WasmException("Invalid 'form' value ('" + form + "') for function type."); } uint paramCount = reader.ReadVarUInt32(); var paramTypes = new List <WasmValueType>((int)paramCount); for (uint i = 0; i < paramCount; i++) { paramTypes.Add(reader.ReadWasmValueType()); } uint retCount = reader.ReadVarUInt32(); var retTypes = new List <WasmValueType>((int)retCount); for (uint i = 0; i < retCount; i++) { retTypes.Add(reader.ReadWasmValueType()); } return(new FunctionType(paramTypes, retTypes)); }
/// <summary> /// Reads a single table description from the given reader. /// </summary> /// <returns>The table description.</returns> public static TableType ReadFrom(BinaryWasmReader reader) { var elemType = (WasmType)reader.ReadWasmType(); var limits = reader.ReadResizableLimits(); return(new TableType(elemType, limits)); }
/// <summary> /// Reads a binary WebAssembly from the given stream. /// </summary> /// <param name="source">The stream from which a WebAssembly file is to be read.</param> /// <param name="streamIsEmpty">Tests if the input stream is empty.</param> /// <returns>The WebAssembly file.</returns> public static WasmFile ReadBinary(Stream source, Func <bool> streamIsEmpty) { // Create a WebAssembly reader and read the file. var reader = new BinaryReader(source); var wasmReader = new BinaryWasmReader(reader, streamIsEmpty); return(wasmReader.ReadFile()); }
/// <summary> /// Reads a binary WebAssembly from the given stream. /// </summary> /// <param name="Source">The stream from which a WebAssembly file is to be read.</param> /// <returns>The WebAssembly file.</returns> public static WasmFile ReadBinary(Stream Source) { // Create a WebAssembly reader and read the file. var reader = new BinaryReader(Source); var wasmReader = new BinaryWasmReader(reader); return(wasmReader.ReadFile()); }
/// <summary> /// Reads a data segment from the given WebAssembly reader. /// </summary> /// <param name="Reader">The WebAssembly reader.</param> /// <returns>The data segment that was read from the reader.</returns> public static DataSegment ReadFrom(BinaryWasmReader Reader) { var index = Reader.ReadVarUInt32(); var offset = InitializerExpression.ReadFrom(Reader); var dataLength = Reader.ReadVarUInt32(); var data = Reader.ReadBytes((int)dataLength); return(new DataSegment(index, offset, data)); }
/// <summary> /// Reads the start section with the given header. /// </summary> /// <param name="header">The section header.</param> /// <param name="reader">The WebAssembly file reader.</param> /// <returns>The parsed section.</returns> public static StartSection ReadSectionPayload(SectionHeader header, BinaryWasmReader reader) { long startPos = reader.Position; // Read the start function index. uint startIndex = reader.ReadVarUInt32(); // Skip any remaining bytes. var extraPayload = reader.ReadRemainingPayload(startPos, header); return(new StartSection(startIndex, extraPayload)); }
/// <summary> /// Reads the name section with the given header. /// </summary> /// <param name="Header">The section header.</param> /// <param name="Reader">The WebAssembly file reader.</param> /// <returns>The parsed section.</returns> public static NameSection ReadSectionPayload(SectionHeader Header, BinaryWasmReader Reader) { var section = new NameSection(); long startPos = Reader.Position; while (Reader.Position - startPos < Header.PayloadLength) { // Read entries until we've read the entire section. section.Names.Add(NameEntry.Read(Reader)); } return(section); }
/// <summary> /// Reads an element segment from the given WebAssembly reader. /// </summary> /// <param name="Reader">The WebAssembly reader.</param> /// <returns>The element segment that was read from the reader.</returns> public static ElementSegment ReadFrom(BinaryWasmReader Reader) { var index = Reader.ReadVarUInt32(); var offset = InitializerExpression.ReadFrom(Reader); var dataLength = Reader.ReadVarUInt32(); var elements = new List <uint>((int)dataLength); for (uint i = 0; i < dataLength; i++) { elements.Add(Reader.ReadVarUInt32()); } return(new ElementSegment(index, offset, elements)); }
/// <summary> /// Reads the immediates (not the opcode) of a WebAssembly instruction /// for this operator from the given reader and returns the result as an /// instruction. /// </summary> /// <param name="Reader">The WebAssembly file reader to read immediates from.</param> /// <returns>A WebAssembly instruction.</returns> public override Instruction ReadImmediates(BinaryWasmReader Reader) { uint tableSize = Reader.ReadVarUInt32(); var tableEntries = new List <uint>((int)tableSize); for (uint i = 0; i < tableSize; i++) { tableEntries.Add(Reader.ReadVarUInt32()); } uint defaultEntry = Reader.ReadVarUInt32(); return(Create(tableEntries, defaultEntry)); }
/// <summary> /// Reads a type section's payload from the given binary WebAssembly reader. /// </summary> /// <param name="header">The type section's header.</param> /// <param name="reader">A reader for a binary WebAssembly file.</param> /// <returns>A parsed type section.</returns> public static TypeSection ReadSectionPayload(SectionHeader header, BinaryWasmReader reader) { long initPos = reader.Position; uint typeCount = reader.ReadVarUInt32(); var types = new List <FunctionType>((int)typeCount); for (uint i = 0; i < typeCount; i++) { types.Add(FunctionType.ReadFrom(reader)); } var extraBytes = reader.ReadRemainingPayload(initPos, header); return(new TypeSection(types, extraBytes)); }
/// <summary> /// Reads a name entry's header and payload from the given binary /// WebAssembly reader. /// </summary> /// <param name="Reader">The reader to read the name entry from.</param> /// <returns>A name entry.</returns> public static NameEntry Read(BinaryWasmReader Reader) { NameEntryKind kind = (NameEntryKind)Reader.ReadVarUInt7(); uint length = Reader.ReadVarUInt32(); switch (kind) { case NameEntryKind.Module: return(ModuleNameEntry.ReadPayload(Reader, length)); default: return(UnknownNameEntry.ReadPayload(Reader, kind, length)); } }
/// <summary> /// Reads a table section's payload from the given binary WebAssembly reader. /// </summary> /// <param name="Header">The type section's header.</param> /// <param name="Reader">A reader for a binary WebAssembly file.</param> /// <returns>A parsed type section.</returns> public static TableSection ReadSectionPayload(SectionHeader Header, BinaryWasmReader Reader) { long initPos = Reader.Position; uint typeCount = Reader.ReadVarUInt32(); var tables = new List <TableType>((int)typeCount); for (uint i = 0; i < typeCount; i++) { tables.Add(TableType.ReadFrom(Reader)); } var extraBytes = Reader.ReadRemainingPayload(initPos, Header); return(new TableSection(tables, extraBytes)); }
/// <summary> /// Reads the global section with the given header. /// </summary> /// <param name="header">The section header.</param> /// <param name="reader">The WebAssembly file reader.</param> /// <returns>The parsed section.</returns> public static GlobalSection ReadSectionPayload(SectionHeader header, BinaryWasmReader reader) { long startPos = reader.Position; // Read the global variable definitions. uint count = reader.ReadVarUInt32(); var globalVars = new List <GlobalVariable>(); for (uint i = 0; i < count; i++) { globalVars.Add(GlobalVariable.ReadFrom(reader)); } // Skip any remaining bytes. var extraPayload = reader.ReadRemainingPayload(startPos, header); return(new GlobalSection(globalVars, extraPayload)); }
/// <summary> /// Reads the function section with the given header. /// </summary> /// <param name="header">The section header.</param> /// <param name="reader">The WebAssembly file reader.</param> /// <returns>The parsed section.</returns> public static FunctionSection ReadSectionPayload(SectionHeader header, BinaryWasmReader reader) { long startPos = reader.Position; // Read the function indices. uint count = reader.ReadVarUInt32(); var funcTypes = new List <uint>(); for (uint i = 0; i < count; i++) { funcTypes.Add(reader.ReadVarUInt32()); } // Skip any remaining bytes. var extraPayload = reader.ReadRemainingPayload(startPos, header); return(new FunctionSection(funcTypes, extraPayload)); }
/// <summary> /// Reads the memory section with the given header. /// </summary> /// <param name="Header">The section header.</param> /// <param name="Reader">The WebAssembly file reader.</param> /// <returns>The parsed section.</returns> public static MemorySection ReadSectionPayload(SectionHeader Header, BinaryWasmReader Reader) { long startPos = Reader.Position; // Read the resizable limits. uint count = Reader.ReadVarUInt32(); var limits = new List <MemoryType>(); for (uint i = 0; i < count; i++) { limits.Add(MemoryType.ReadFrom(Reader)); } // Skip any remaining bytes. var extraPayload = Reader.ReadRemainingPayload(startPos, Header); return(new MemorySection(limits, extraPayload)); }
/// <summary> /// Reads the import section with the given header. /// </summary> /// <param name="Header">The section header.</param> /// <param name="Reader">A reader for a binary WebAssembly file.</param> /// <returns>The parsed section.</returns> public static ImportSection ReadSectionPayload( SectionHeader Header, BinaryWasmReader Reader) { long startPos = Reader.Position; // Read the imported values. uint count = Reader.ReadVarUInt32(); var importedVals = new List <ImportedValue>(); for (uint i = 0; i < count; i++) { importedVals.Add(ImportedValue.ReadFrom(Reader)); } // Skip any remaining bytes. var extraPayload = Reader.ReadRemainingPayload(startPos, Header); return(new ImportSection(importedVals, extraPayload)); }
/// <summary> /// Reads the child instructions of a WebAssembly block from the given reader. /// </summary> /// <param name="BlockType">The type of value returned by the resulting block.</param> /// <param name="Reader">The WebAssembly file reader.</param> /// <returns>A WebAssembly block instruction.</returns> public BlockInstruction ReadBlockContents(WasmType BlockType, BinaryWasmReader Reader) { var contents = new List <Instruction>(); while (true) { byte opCode = Reader.ReadByte(); if (opCode == Operators.EndOpCode) { return(Create(BlockType, contents)); } else { var op = Operators.GetOperatorByOpCode(opCode); contents.Add(op.ReadImmediates(Reader)); } } }
/// <summary> /// Reads the code section with the given header. /// </summary> /// <param name="Header">The section header.</param> /// <param name="Reader">A reader for a binary WebAssembly file.</param> /// <returns>The parsed section.</returns> public static CodeSection ReadSectionPayload( SectionHeader Header, BinaryWasmReader Reader) { long startPos = Reader.Position; // Read the function bodies. uint count = Reader.ReadVarUInt32(); var funcBodies = new List <FunctionBody>(); for (uint i = 0; i < count; i++) { funcBodies.Add(FunctionBody.ReadFrom(Reader)); } // Skip any remaining bytes. var extraPayload = Reader.ReadRemainingPayload(startPos, Header); return(new CodeSection(funcBodies, extraPayload)); }
/// <summary> /// Reads the export section with the given header. /// </summary> /// <param name="Header">The section header.</param> /// <param name="Reader">A reader for a binary WebAssembly file.</param> /// <returns>The parsed section.</returns> public static DataSection ReadSectionPayload( SectionHeader Header, BinaryWasmReader Reader) { long startPos = Reader.Position; // Read the data segments. uint count = Reader.ReadVarUInt32(); var exportedVals = new List <DataSegment>(); for (uint i = 0; i < count; i++) { exportedVals.Add(DataSegment.ReadFrom(Reader)); } // Skip any remaining bytes. var extraPayload = Reader.ReadRemainingPayload(startPos, Header); return(new DataSection(exportedVals, extraPayload)); }
/// <summary> /// Reads the element section with the given header. /// </summary> /// <param name="Header">The section header.</param> /// <param name="Reader">A reader for a binary WebAssembly file.</param> /// <returns>The parsed section.</returns> public static ElementSection ReadSectionPayload( SectionHeader Header, BinaryWasmReader Reader) { long startPos = Reader.Position; // Read the element segments. uint count = Reader.ReadVarUInt32(); var segments = new List <ElementSegment>(); for (uint i = 0; i < count; i++) { segments.Add(ElementSegment.ReadFrom(Reader)); } // Skip any remaining bytes. var extraPayload = Reader.ReadRemainingPayload(startPos, Header); return(new ElementSection(segments, extraPayload)); }
/// <summary> /// Reads the export section with the given header. /// </summary> /// <param name="header">The section header.</param> /// <param name="reader">A reader for a binary WebAssembly file.</param> /// <returns>The parsed section.</returns> public static ExportSection ReadSectionPayload( SectionHeader header, BinaryWasmReader reader) { long startPos = reader.Position; // Read the function indices. uint count = reader.ReadVarUInt32(); var exportedVals = new List <ExportedValue>(); for (uint i = 0; i < count; i++) { exportedVals.Add( new ExportedValue( reader.ReadString(), (ExternalKind)reader.ReadByte(), reader.ReadVarUInt32())); } // Skip any remaining bytes. var extraPayload = reader.ReadRemainingPayload(startPos, header); return(new ExportSection(exportedVals, extraPayload)); }
/// <summary> /// Reads an imported value from the given binary WebAssembly reader. /// </summary> /// <param name="Reader">The WebAssembly reader.</param> /// <returns>The imported value that was read.</returns> public static ImportedValue ReadFrom(BinaryWasmReader Reader) { string moduleName = Reader.ReadString(); string fieldName = Reader.ReadString(); var kind = (ExternalKind)Reader.ReadByte(); switch (kind) { case ExternalKind.Function: return(new ImportedFunction(moduleName, fieldName, Reader.ReadVarUInt32())); case ExternalKind.Global: return(new ImportedGlobal(moduleName, fieldName, GlobalType.ReadFrom(Reader))); case ExternalKind.Memory: return(new ImportedMemory(moduleName, fieldName, MemoryType.ReadFrom(Reader))); case ExternalKind.Table: return(new ImportedTable(moduleName, fieldName, TableType.ReadFrom(Reader))); default: throw new WasmException("Unknown imported value kind: " + kind); } }
/// <summary> /// Reads the immediates (not the opcode) of a WebAssembly instruction /// for this operator from the given reader and returns the result as an /// instruction. /// </summary> /// <param name="reader">The WebAssembly file reader to read immediates from.</param> /// <returns>A WebAssembly instruction.</returns> public override Instruction ReadImmediates(BinaryWasmReader reader) { return(new CallIndirectInstruction(this, reader.ReadVarUInt32(), reader.ReadVarUInt32())); }
/// <summary> /// Reads the immediates (not the opcode) of a WebAssembly instruction /// for this operator from the given reader and returns the result as an /// instruction. /// </summary> /// <param name="reader">The WebAssembly file reader to read immediates from.</param> /// <returns>A WebAssembly instruction.</returns> public override Instruction ReadImmediates(BinaryWasmReader reader) { return(Create(reader.ReadFloat32())); }
/// <summary> /// Reads an initializer expression from the given WebAssembly reader. /// </summary> /// <param name="Reader">The WebAssembly reader.</param> /// <returns>The parsed initializer expression.</returns> public static InitializerExpression ReadFrom(BinaryWasmReader Reader) { return(new InitializerExpression( Operators.Block.ReadBlockContents(WasmType.Empty, Reader).Contents)); }
/// <summary> /// Reads the immediates (not the opcode) of a WebAssembly instruction /// for this operator from the given reader and returns the result as an /// instruction. /// </summary> /// <param name="Reader">The WebAssembly file reader to read immediates from.</param> /// <returns>A WebAssembly instruction.</returns> public override Instruction ReadImmediates(BinaryWasmReader Reader) { var type = Reader.ReadWasmType(); return(ReadBlockContents(type, Reader)); }
/// <summary> /// Reads a single memory description from the given reader. /// </summary> /// <returns>The memory description.</returns> public static MemoryType ReadFrom(BinaryWasmReader Reader) { return(new MemoryType(Reader.ReadResizableLimits())); }