Пример #1
0
        /// <summary></summary>
        /// <param name="reader"></param>
        /// <returns>false if we reached end of file. If result is true, the caller is
        /// expected to invoke us again for next section discovery.</returns>
        private bool ParseSection(BinaryParsingReader reader)
        {
            SectionTypes sectionType;

            try {
                sectionType = (SectionTypes)reader.ReadVarUint7();
                if (!Enum.IsDefined(typeof(SectionTypes), sectionType))
                {
                    throw new WasmParsingException(string.Format(
                                                       ParsingErrorMessages.UnknownSectionType, sectionType));
                }
                Console.WriteLine("Parsing {0} section.", sectionType);
            }
            catch (EndOfStreamException e) {
                // This is expected. Section parsing is complete.
                return(false);
            }
            try {
                ParseSection(reader, sectionType);
                return(true);
            }
            catch (EndOfStreamException e) {
                // This is unexpected. We are stopping in the midst of a section.
                throw new WasmParsingException(ParsingErrorMessages.IncompleteSectionEncountered);
            }
        }
Пример #2
0
        private void ParseImportSection(BinaryParsingReader reader, uint payloadSize)
        {
            long startPosition = payloadSize;
            uint importsCount  = reader.ReadVarUint32();

            for (uint index = 0; index < importsCount; index++)
            {
                string moduleName = reader.ReadLengthPrefixedUTF8String();
                List <ImportedItemDefinition> imports;
                if (!_perModuleImportedItems.TryGetValue(moduleName, out imports))
                {
                    imports = new List <ImportedItemDefinition>();
                    _perModuleImportedItems.Add(moduleName, imports);
                }
                string       fieldName = reader.ReadLengthPrefixedUTF8String();
                ExternalKind kind      = (ExternalKind)reader.ReadVarUint7();
                bool         maxPresent;
                uint         initialLength;
                uint         maximumLength;
                switch (kind)
                {
                case ExternalKind.Function:
                    imports.Add(new ImportedFunctionDefinition(fieldName, reader.ReadVarUint32()));
                    continue;

                case ExternalKind.Global:
                    bool mutable;
                    BuiltinLanguageType contentType = reader.ReadGlobaltype(out mutable);
                    imports.Add(new ImportedGlobalDefinition(fieldName, contentType, mutable));
                    continue;

                case ExternalKind.Memory:
                    maxPresent    = (0 != reader.ReadVarUint1());
                    initialLength = reader.ReadVarUint32();
                    maximumLength = maxPresent ? reader.ReadVarUint32() : 0;
                    imports.Add(new ImportedMemoryDefinition(fieldName, initialLength, maxPresent ? (uint?)maximumLength : null));
                    continue;

                case ExternalKind.Table:
                    BuiltinLanguageType elementType = (BuiltinLanguageType)reader.ReadVarInt7();
                    if (BuiltinLanguageType.AnyFunc != elementType)
                    {
                        throw new WasmParsingException(string.Format(ParsingErrorMessages.UnexpectedBuiltinType,
                                                                     elementType, BuiltinLanguageType.AnyFunc));
                    }
                    maxPresent    = (0 != reader.ReadVarUint1());
                    initialLength = reader.ReadVarUint32();
                    maximumLength = maxPresent ? reader.ReadVarUint32() : 0;
                    imports.Add(new ImportedTableDefinition(fieldName, elementType, initialLength,
                                                            maxPresent ? (uint?)maximumLength : null));
                    continue;

                default:
                    throw new WasmParsingException(string.Format(
                                                       ParsingErrorMessages.UnrecognizedExternalKind, kind));
                }
            }
            // TODO Check for match between payloadSize and current stream position.
            return;
        }
Пример #3
0
        private void ParseDataSection(BinaryParsingReader reader, uint payloadSize)
        {
            uint dataSegmentsCount = reader.ReadVarUint32();

            _dataSegments = new List <DataSegment>();
            for (uint index = 0; index < dataSegmentsCount; index++)
            {
                _dataSegments.Add(DataSegment.Create(reader));
            }
            return;
        }
Пример #4
0
        private void ParseFunctionSection(BinaryParsingReader reader, uint payloadSize)
        {
            long startPosition  = payloadSize;
            uint functionsCount = reader.ReadVarUint32();

            for (uint index = 0; index < functionsCount; index++)
            {
                uint signatureIndex = reader.ReadVarUint32();
                _functions.Add(new FunctionDefinition(_functionSignatures[(int)signatureIndex]));
            }
        }
Пример #5
0
            internal static DataSegment Create(BinaryParsingReader reader)
            {
                uint linearMemoryIndex = reader.ReadVarUint32();
                List <Instruction> offsetExpression = reader.ReadInitializationExpression();
                uint dataSize = reader.ReadVarUint32();

                byte[] data = reader.ReadBytes((int)dataSize);
                return(new DataSegment()
                {
                    LinearMemoryIndex = linearMemoryIndex, Data = data, OffsetExpression = offsetExpression
                });
            }
Пример #6
0
        private void ParseExportSection(BinaryParsingReader reader, uint payloadSize)
        {
            long startPosition = payloadSize;
            uint exportsCount  = reader.ReadVarUint32();

            for (uint index = 0; index < exportsCount; index++)
            {
                string exportName = reader.ReadLengthPrefixedUTF8String();
                // TODO : Interpret below fields.
                byte exportKind      = reader.ReadByte();
                uint indexSpaceIndex = reader.ReadVarUint32();
            }
        }
Пример #7
0
 /// <summary></summary>
 /// <param name="from"></param>
 /// <remarks>Module specification is defined by :
 /// http://webassembly.org/docs/binary-encoding/#high-level-structure
 /// </remarks>
 private bool Parse(Stream from)
 {
     using (BinaryParsingReader reader = new BinaryParsingReader(from)) {
         _decoder = new InstructionDecoder(reader);
         ParseMagicNumberAndVersion(reader);
         while (ParseSection(reader))
         {
             ;
         }
     }
     DumpStatistics();
     return(true);
 }
Пример #8
0
        private void ParseTypeSection(BinaryParsingReader reader, uint payloadSize)
        {
            long startPosition  = payloadSize;
            uint functionsCount = reader.ReadVarUint32();

            for (uint index = 0; index < functionsCount; index++)
            {
                FunctionSignature function = FunctionSignature.Parse(reader);
                _functionSignatures.Add(function);
            }
            // TODO Check for match between payloadSize and current stream position.
            return;
        }
Пример #9
0
        private void ParseCodeSection(BinaryParsingReader reader, uint payloadSize)
        {
            uint functionBodyCount = reader.ReadVarUint32();

            if (functionBodyCount != _functions.Count)
            {
                throw new WasmParsingException(
                          ParsingErrorMessages.FunctionDefVsBodyCountMismatch);
            }
            for (uint functionIndex = 0; functionIndex < functionBodyCount; functionIndex++)
            {
                ParseFunctionBody(reader, _functions[(int)functionIndex]);
            }
        }
Пример #10
0
        private void ParseGlobalSection(BinaryParsingReader reader, uint payloadSize)
        {
            uint globalVariablesCount = reader.ReadVarUint32();

            for (uint index = 0; index < globalVariablesCount; index++)
            {
                bool mutable;
                BuiltinLanguageType contentType = reader.ReadGlobaltype(out mutable);
                List <Instruction>  initializer = reader.ReadInitializationExpression();

                GlobalVariable variable = new GlobalVariable(contentType, mutable, initializer);
                _globalVariables.Add(variable);
            }
        }
Пример #11
0
        private void ParseElementSection(BinaryParsingReader reader, uint payloadSize)
        {
            uint elementsCount = reader.ReadVarUint32();

            for (uint index = 0; index < elementsCount; index++)
            {
                uint tableIndex = reader.ReadVarUint32();
                List <Instruction> initializer = reader.ReadInitializationExpression();
                uint elementCount = reader.ReadVarUint32();
                for (int elementIndex = 0; elementIndex < elementCount; elementIndex++)
                {
                    uint element = reader.ReadVarUint32();
                }
            }
        }
Пример #12
0
            internal static Element Create(BinaryParsingReader reader)
            {
                uint tableIndex = reader.ReadVarUint32();
                List <Instruction> offsetExpression = reader.ReadInitializationExpression();
                uint elementsCount = reader.ReadVarUint32();

                uint[] elements = new uint[elementsCount];
                for (int index = 0; index < elementsCount; index++)
                {
                    elements[index] = reader.ReadVarUint32();
                }
                return(new Element()
                {
                    Elements = elements, OffsetExpression = offsetExpression, TableIndex = tableIndex
                });
            }
Пример #13
0
        internal static FunctionSignature Parse(BinaryParsingReader reader)
        {
            FunctionSignature result = new FunctionSignature();

            reader.ReadAndAssertLanguageType(-32);
            uint parametersCount = reader.ReadVarUint32();

            for (uint index = 0; index < parametersCount; index++)
            {
                result._parametersType.Add((BuiltinLanguageType)reader.ReadValueType());
            }

            result.ReturnType = (1 == reader.ReadVarUint1())
                ? (BuiltinLanguageType)reader.ReadValueType()
                : BuiltinLanguageType.EmptyBlock;
            return(result);
        }
Пример #14
0
        private void ParseMagicNumberAndVersion(BinaryParsingReader reader)
        {
            int magicNumber = reader.ReadInt32();

            if (MagicModuleNumber != magicNumber)
            {
                throw new WasmParsingException(string.Format(
                                                   ParsingErrorMessages.MissingModuleMagicNumber, MagicModuleNumber, magicNumber));
            }
            int version = reader.ReadInt32();

            if ((MaximumSupportedModuleFormatVersion < version) ||
                (MinimumSupportedModuleFormatVersion > version))
            {
                throw new WasmParsingException(string.Format(
                                                   ParsingErrorMessages.UnsupportedModuleFormatVersion,
                                                   version, MinimumSupportedModuleFormatVersion, MaximumSupportedModuleFormatVersion));
            }
        }
Пример #15
0
        private void ParseFunctionBody(BinaryParsingReader reader, FunctionDefinition target)
        {
            uint bodySize         = reader.ReadVarUint32();
            long startPosition    = reader.BaseStream.Position;
            uint localsEntryCount = reader.ReadVarUint32();

            lock (_currentFunctionLocals) {
                if (0 < localsEntryCount)
                {
                    _currentFunctionLocals.Clear();
                    for (int localEntryIndex = 0; localEntryIndex < localsEntryCount; localEntryIndex++)
                    {
                        uint variablesCount            = reader.ReadVarUint32();
                        BuiltinLanguageType valuesType = (BuiltinLanguageType)reader.ReadValueType();
                        for (uint index = 0; index < variablesCount; index++)
                        {
                            _currentFunctionLocals.Add(valuesType);
                        }
                    }
                    target.SetLocalTypes(_currentFunctionLocals.ToArray());
                }
            }
            List <Instruction> instructions = reader.ReadFunctionBodyCode();
            long endPosition = reader.BaseStream.Position;
            uint trueSize    = (uint)(endPosition - startPosition);

#if TRACE_CODE
            foreach (Instruction instruction in instructions)
            {
                Console.WriteLine(instruction.ToString());
            }
            Console.WriteLine("{0} ================================================", target.Id);
#endif
            if (bodySize != trueSize)
            {
                throw new WasmParsingException(string.Format(
                                                   ParsingErrorMessages.FunctionBodyLengthMismatch, bodySize, trueSize));
            }
            target.SetBody(instructions);
            return;
        }
Пример #16
0
 internal InstructionDecoder(BinaryParsingReader reader)
 {
     _reader = reader;
 }
Пример #17
0
        private WasmModuleSection ParseSection(BinaryParsingReader reader, SectionTypes type)
        {
            WasmModuleSection result = null;
            // The specification is not very clear about the fact that the value of the
            // payload_len field from section header doesn't include neither this field
            // length, nor the previous section code. We have to read the payload_data
            // field definition to understand this.
            uint payloadSize = reader.ReadVarUint32();

            string sectionName = null;

            if (0 == type)
            {
                long initialStreamPosition = reader.BaseStream.Position;
                sectionName  = reader.ReadLengthPrefixedUTF8String();
                payloadSize -= (uint)(reader.BaseStream.Position - initialStreamPosition);
                result       = new WasmModuleSection(sectionName);

                byte[] sectionData = new byte[payloadSize];
                reader.Read(sectionData, 0, sectionData.Length);
                result.SetRawData(sectionData);
                _customSections.Add(result);
                return(result);
            }
            // This test will ensure a non custom section can't be parsed twice as per
            // the specification. We seems to be more stringent here than the specification
            // that seems to state that the section COULD be ignored.
            if (type <= _lastParsedSectionType)
            {
                throw new WasmParsingException(string.Format(ParsingErrorMessages.InvalidSectionDefinitionOrder,
                                                             type, _lastParsedSectionType));
            }
            switch (type)
            {
            case SectionTypes.Code:
                ParseCodeSection(reader, payloadSize);
                break;

            case SectionTypes.Data:
                ParseDataSection(reader, payloadSize);
                break;

            case SectionTypes.Element:
                ParseElementSection(reader, payloadSize);
                break;

            case SectionTypes.Export:
                ParseExportSection(reader, payloadSize);
                break;

            case SectionTypes.Function:
                ParseFunctionSection(reader, payloadSize);
                break;

            case SectionTypes.Global:
                ParseGlobalSection(reader, payloadSize);
                break;

            case SectionTypes.Import:
                ParseImportSection(reader, payloadSize);
                break;

            case SectionTypes.Memory:
                throw new NotImplementedException();

            case SectionTypes.Start:
                throw new NotImplementedException();

            case SectionTypes.Table:
                throw new NotImplementedException();

            case SectionTypes.Type:
                ParseTypeSection(reader, payloadSize);
                break;

            default:
                throw new NotImplementedException();
            }
            _lastParsedSectionType = type;
            return(result);
        }