Example #1
0
        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
            });
        }
Example #2
0
        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
            });
        }
Example #3
0
        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
            });
        }
Example #4
0
        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,
            });
        }
Example #5
0
        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();
            }
        }