| ... | ... | @@ -1231,12 +1231,12 @@ const MachODumper = struct { |
| 1231 | 1231 | } |
| 1232 | 1232 | |
| 1233 | 1233 | fn parseRebaseInfo(ctx: ObjectContext, data: []const u8, rebases: *std.ArrayList(u64)) !void { |
| 1234 | | var br: std.io.Reader = .fixed(data); |
| 1234 | var r: std.io.Reader = .fixed(data); |
| 1235 | 1235 | |
| 1236 | 1236 | var seg_id: ?u8 = null; |
| 1237 | 1237 | var offset: u64 = 0; |
| 1238 | 1238 | while (true) { |
| 1239 | | const byte = br.takeByte() catch break; |
| 1239 | const byte = r.takeByte() catch break; |
| 1240 | 1240 | const opc = byte & macho.REBASE_OPCODE_MASK; |
| 1241 | 1241 | const imm = byte & macho.REBASE_IMMEDIATE_MASK; |
| 1242 | 1242 | switch (opc) { |
| ... | ... | @@ -1244,17 +1244,17 @@ const MachODumper = struct { |
| 1244 | 1244 | macho.REBASE_OPCODE_SET_TYPE_IMM => {}, |
| 1245 | 1245 | macho.REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB => { |
| 1246 | 1246 | seg_id = imm; |
| 1247 | | offset = try br.takeLeb128(u64); |
| 1247 | offset = try r.takeLeb128(u64); |
| 1248 | 1248 | }, |
| 1249 | 1249 | macho.REBASE_OPCODE_ADD_ADDR_IMM_SCALED => { |
| 1250 | 1250 | offset += imm * @sizeOf(u64); |
| 1251 | 1251 | }, |
| 1252 | 1252 | macho.REBASE_OPCODE_ADD_ADDR_ULEB => { |
| 1253 | | const addend = try br.takeLeb128(u64); |
| 1253 | const addend = try r.takeLeb128(u64); |
| 1254 | 1254 | offset += addend; |
| 1255 | 1255 | }, |
| 1256 | 1256 | macho.REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB => { |
| 1257 | | const addend = try br.takeLeb128(u64); |
| 1257 | const addend = try r.takeLeb128(u64); |
| 1258 | 1258 | const seg = ctx.segments.items[seg_id.?]; |
| 1259 | 1259 | const addr = seg.vmaddr + offset; |
| 1260 | 1260 | try rebases.append(addr); |
| ... | ... | @@ -1271,11 +1271,11 @@ const MachODumper = struct { |
| 1271 | 1271 | ntimes = imm; |
| 1272 | 1272 | }, |
| 1273 | 1273 | macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES => { |
| 1274 | | ntimes = try br.takeLeb128(u64); |
| 1274 | ntimes = try r.takeLeb128(u64); |
| 1275 | 1275 | }, |
| 1276 | 1276 | macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB => { |
| 1277 | | ntimes = try br.takeLeb128(u64); |
| 1278 | | skip = try br.takeLeb128(u64); |
| 1277 | ntimes = try r.takeLeb128(u64); |
| 1278 | skip = try r.takeLeb128(u64); |
| 1279 | 1279 | }, |
| 1280 | 1280 | else => unreachable, |
| 1281 | 1281 | } |
| ... | ... | @@ -1341,7 +1341,7 @@ const MachODumper = struct { |
| 1341 | 1341 | } |
| 1342 | 1342 | |
| 1343 | 1343 | fn parseBindInfo(ctx: ObjectContext, data: []const u8, bindings: *std.ArrayList(Binding)) !void { |
| 1344 | | var br: std.io.Reader = .fixed(data); |
| 1344 | var r: std.io.Reader = .fixed(data); |
| 1345 | 1345 | |
| 1346 | 1346 | var seg_id: ?u8 = null; |
| 1347 | 1347 | var tag: Binding.Tag = .self; |
| ... | ... | @@ -1352,7 +1352,7 @@ const MachODumper = struct { |
| 1352 | 1352 | var name_buf: std.io.Writer.Allocating = .init(ctx.gpa); |
| 1353 | 1353 | defer name_buf.deinit(); |
| 1354 | 1354 | |
| 1355 | | while (br.takeByte()) |byte| { |
| 1355 | while (r.takeByte()) |byte| { |
| 1356 | 1356 | const opc = byte & macho.BIND_OPCODE_MASK; |
| 1357 | 1357 | const imm = byte & macho.BIND_IMMEDIATE_MASK; |
| 1358 | 1358 | switch (opc) { |
| ... | ... | @@ -1373,18 +1373,18 @@ const MachODumper = struct { |
| 1373 | 1373 | }, |
| 1374 | 1374 | macho.BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB => { |
| 1375 | 1375 | seg_id = imm; |
| 1376 | | offset = try br.takeLeb128(u64); |
| 1376 | offset = try r.takeLeb128(u64); |
| 1377 | 1377 | }, |
| 1378 | 1378 | macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM => { |
| 1379 | 1379 | name_buf.clearRetainingCapacity(); |
| 1380 | | _ = try br.streamDelimiterLimit(&name_buf.writer, 0, .limited(std.math.maxInt(u32))); |
| 1380 | _ = try r.streamDelimiterLimit(&name_buf.writer, 0, .limited(std.math.maxInt(u32))); |
| 1381 | 1381 | try name_buf.writer.writeByte(0); |
| 1382 | 1382 | }, |
| 1383 | 1383 | macho.BIND_OPCODE_SET_ADDEND_SLEB => { |
| 1384 | | addend = try br.takeLeb128(i64); |
| 1384 | addend = try r.takeLeb128(i64); |
| 1385 | 1385 | }, |
| 1386 | 1386 | macho.BIND_OPCODE_ADD_ADDR_ULEB => { |
| 1387 | | const x = try br.takeLeb128(u64); |
| 1387 | const x = try r.takeLeb128(u64); |
| 1388 | 1388 | offset = @intCast(@as(i64, @intCast(offset)) + @as(i64, @bitCast(x))); |
| 1389 | 1389 | }, |
| 1390 | 1390 | macho.BIND_OPCODE_DO_BIND, |
| ... | ... | @@ -1399,14 +1399,14 @@ const MachODumper = struct { |
| 1399 | 1399 | switch (opc) { |
| 1400 | 1400 | macho.BIND_OPCODE_DO_BIND => {}, |
| 1401 | 1401 | macho.BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB => { |
| 1402 | | add_addr = try br.takeLeb128(u64); |
| 1402 | add_addr = try r.takeLeb128(u64); |
| 1403 | 1403 | }, |
| 1404 | 1404 | macho.BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED => { |
| 1405 | 1405 | add_addr = imm * @sizeOf(u64); |
| 1406 | 1406 | }, |
| 1407 | 1407 | macho.BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB => { |
| 1408 | | count = try br.takeLeb128(u64); |
| 1409 | | skip = try br.takeLeb128(u64); |
| 1408 | count = try r.takeLeb128(u64); |
| 1409 | skip = try r.takeLeb128(u64); |
| 1410 | 1410 | }, |
| 1411 | 1411 | else => unreachable, |
| 1412 | 1412 | } |
| ... | ... | @@ -1437,8 +1437,8 @@ const MachODumper = struct { |
| 1437 | 1437 | defer arena.deinit(); |
| 1438 | 1438 | |
| 1439 | 1439 | var exports: std.ArrayList(Export) = .init(arena.allocator()); |
| 1440 | | var br: std.io.Reader = .fixed(data); |
| 1441 | | try parseTrieNode(arena.allocator(), &br, "", &exports); |
| 1440 | var r: std.io.Reader = .fixed(data); |
| 1441 | try parseTrieNode(arena.allocator(), &r, "", &exports); |
| 1442 | 1442 | |
| 1443 | 1443 | mem.sort(Export, exports.items, {}, Export.lessThan); |
| 1444 | 1444 | |
| ... | ... | @@ -1506,17 +1506,17 @@ const MachODumper = struct { |
| 1506 | 1506 | |
| 1507 | 1507 | fn parseTrieNode( |
| 1508 | 1508 | arena: Allocator, |
| 1509 | | br: *std.io.Reader, |
| 1509 | r: *std.io.Reader, |
| 1510 | 1510 | prefix: []const u8, |
| 1511 | 1511 | exports: *std.ArrayList(Export), |
| 1512 | 1512 | ) !void { |
| 1513 | | const size = try br.takeLeb128(u64); |
| 1513 | const size = try r.takeLeb128(u64); |
| 1514 | 1514 | if (size > 0) { |
| 1515 | | const flags = try br.takeLeb128(u8); |
| 1515 | const flags = try r.takeLeb128(u8); |
| 1516 | 1516 | switch (flags) { |
| 1517 | 1517 | macho.EXPORT_SYMBOL_FLAGS_REEXPORT => { |
| 1518 | | const ord = try br.takeLeb128(u64); |
| 1519 | | const name = try br.takeSentinel(0); |
| 1518 | const ord = try r.takeLeb128(u64); |
| 1519 | const name = try r.takeSentinel(0); |
| 1520 | 1520 | try exports.append(.{ |
| 1521 | 1521 | .name = if (name.len > 0) name else prefix, |
| 1522 | 1522 | .tag = .reexport, |
| ... | ... | @@ -1524,8 +1524,8 @@ const MachODumper = struct { |
| 1524 | 1524 | }); |
| 1525 | 1525 | }, |
| 1526 | 1526 | macho.EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER => { |
| 1527 | | const stub_offset = try br.takeLeb128(u64); |
| 1528 | | const resolver_offset = try br.takeLeb128(u64); |
| 1527 | const stub_offset = try r.takeLeb128(u64); |
| 1528 | const resolver_offset = try r.takeLeb128(u64); |
| 1529 | 1529 | try exports.append(.{ |
| 1530 | 1530 | .name = prefix, |
| 1531 | 1531 | .tag = .stub_resolver, |
| ... | ... | @@ -1536,7 +1536,7 @@ const MachODumper = struct { |
| 1536 | 1536 | }); |
| 1537 | 1537 | }, |
| 1538 | 1538 | else => { |
| 1539 | | const vmoff = try br.takeLeb128(u64); |
| 1539 | const vmoff = try r.takeLeb128(u64); |
| 1540 | 1540 | try exports.append(.{ |
| 1541 | 1541 | .name = prefix, |
| 1542 | 1542 | .tag = .@"export", |
| ... | ... | @@ -1555,15 +1555,15 @@ const MachODumper = struct { |
| 1555 | 1555 | } |
| 1556 | 1556 | } |
| 1557 | 1557 | |
| 1558 | | const nedges = try br.takeByte(); |
| 1558 | const nedges = try r.takeByte(); |
| 1559 | 1559 | for (0..nedges) |_| { |
| 1560 | | const label = try br.takeSentinel(0); |
| 1561 | | const off = try br.takeLeb128(usize); |
| 1560 | const label = try r.takeSentinel(0); |
| 1561 | const off = try r.takeLeb128(usize); |
| 1562 | 1562 | const prefix_label = try std.fmt.allocPrint(arena, "{s}{s}", .{ prefix, label }); |
| 1563 | | const seek = br.seek; |
| 1564 | | br.seek = off; |
| 1565 | | try parseTrieNode(arena, br, prefix_label, exports); |
| 1566 | | br.seek = seek; |
| 1563 | const seek = r.seek; |
| 1564 | r.seek = off; |
| 1565 | try parseTrieNode(arena, r, prefix_label, exports); |
| 1566 | r.seek = seek; |
| 1567 | 1567 | } |
| 1568 | 1568 | } |
| 1569 | 1569 | |
| ... | ... | @@ -1693,9 +1693,9 @@ const ElfDumper = struct { |
| 1693 | 1693 | |
| 1694 | 1694 | fn parseAndDumpArchive(step: *Step, check: Check, bytes: []const u8) ![]const u8 { |
| 1695 | 1695 | const gpa = step.owner.allocator; |
| 1696 | | var br: std.io.Reader = .fixed(bytes); |
| 1696 | var r: std.io.Reader = .fixed(bytes); |
| 1697 | 1697 | |
| 1698 | | if (!mem.eql(u8, try br.takeArray(elf.ARMAG.len), elf.ARMAG)) return error.InvalidArchiveMagicNumber; |
| 1698 | if (!mem.eql(u8, try r.takeArray(elf.ARMAG.len), elf.ARMAG)) return error.InvalidArchiveMagicNumber; |
| 1699 | 1699 | |
| 1700 | 1700 | var ctx: ArchiveContext = .{ |
| 1701 | 1701 | .gpa = gpa, |
| ... | ... | @@ -1706,14 +1706,14 @@ const ElfDumper = struct { |
| 1706 | 1706 | }; |
| 1707 | 1707 | defer ctx.deinit(); |
| 1708 | 1708 | |
| 1709 | | while (br.seek < bytes.len) { |
| 1710 | | const hdr_seek = std.mem.alignForward(usize, br.seek, 2); |
| 1711 | | br.seek = hdr_seek; |
| 1712 | | const hdr = try br.takeStruct(elf.ar_hdr); |
| 1709 | while (r.seek < bytes.len) { |
| 1710 | const hdr_seek = std.mem.alignForward(usize, r.seek, 2); |
| 1711 | r.seek = hdr_seek; |
| 1712 | const hdr = try r.takeStruct(elf.ar_hdr); |
| 1713 | 1713 | |
| 1714 | 1714 | if (!mem.eql(u8, &hdr.ar_fmag, elf.ARFMAG)) return error.InvalidArchiveHeaderMagicNumber; |
| 1715 | 1715 | |
| 1716 | | const data = try br.take(try hdr.size()); |
| 1716 | const data = try r.take(try hdr.size()); |
| 1717 | 1717 | |
| 1718 | 1718 | if (hdr.isSymtab()) { |
| 1719 | 1719 | try ctx.parseSymtab(data, .p32); |
| ... | ... | @@ -1766,17 +1766,17 @@ const ElfDumper = struct { |
| 1766 | 1766 | } |
| 1767 | 1767 | |
| 1768 | 1768 | fn parseSymtab(ctx: *ArchiveContext, data: []const u8, ptr_width: enum { p32, p64 }) !void { |
| 1769 | | var br: std.io.Reader = .fixed(data); |
| 1769 | var r: std.io.Reader = .fixed(data); |
| 1770 | 1770 | const num = switch (ptr_width) { |
| 1771 | | .p32 => try br.takeInt(u32, .big), |
| 1772 | | .p64 => try br.takeInt(u64, .big), |
| 1771 | .p32 => try r.takeInt(u32, .big), |
| 1772 | .p64 => try r.takeInt(u64, .big), |
| 1773 | 1773 | }; |
| 1774 | 1774 | const ptr_size: usize = switch (ptr_width) { |
| 1775 | 1775 | .p32 => @sizeOf(u32), |
| 1776 | 1776 | .p64 => @sizeOf(u64), |
| 1777 | 1777 | }; |
| 1778 | | _ = try br.discard(.limited(num * ptr_size)); |
| 1779 | | const strtab = br.buffered(); |
| 1778 | _ = try r.discard(.limited(num * ptr_size)); |
| 1779 | const strtab = r.buffered(); |
| 1780 | 1780 | |
| 1781 | 1781 | assert(ctx.symtab.len == 0); |
| 1782 | 1782 | ctx.symtab = try ctx.gpa.alloc(ArSymtabEntry, num); |
| ... | ... | @@ -1784,8 +1784,8 @@ const ElfDumper = struct { |
| 1784 | 1784 | var stroff: usize = 0; |
| 1785 | 1785 | for (ctx.symtab) |*entry| { |
| 1786 | 1786 | const off = switch (ptr_width) { |
| 1787 | | .p32 => try br.takeInt(u32, .big), |
| 1788 | | .p64 => try br.takeInt(u64, .big), |
| 1787 | .p32 => try r.takeInt(u32, .big), |
| 1788 | .p64 => try r.takeInt(u64, .big), |
| 1789 | 1789 | }; |
| 1790 | 1790 | const name = mem.sliceTo(@as([*:0]const u8, @ptrCast(strtab[stroff..].ptr)), 0); |
| 1791 | 1791 | stroff += name.len + 1; |
| ... | ... | @@ -1836,9 +1836,9 @@ const ElfDumper = struct { |
| 1836 | 1836 | |
| 1837 | 1837 | fn parseAndDumpObject(step: *Step, check: Check, bytes: []const u8) ![]const u8 { |
| 1838 | 1838 | const gpa = step.owner.allocator; |
| 1839 | | var br: std.io.Reader = .fixed(bytes); |
| 1839 | var r: std.io.Reader = .fixed(bytes); |
| 1840 | 1840 | |
| 1841 | | const hdr = try br.takeStruct(elf.Elf64_Ehdr); |
| 1841 | const hdr = try r.takeStruct(elf.Elf64_Ehdr); |
| 1842 | 1842 | if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidMagicNumber; |
| 1843 | 1843 | |
| 1844 | 1844 | const shdrs = @as([*]align(1) const elf.Elf64_Shdr, @ptrCast(bytes[hdr.e_shoff..].ptr))[0..hdr.e_shnum]; |
| ... | ... | @@ -2327,9 +2327,9 @@ const WasmDumper = struct { |
| 2327 | 2327 | |
| 2328 | 2328 | fn parseAndDump(step: *Step, check: Check, bytes: []const u8) ![]const u8 { |
| 2329 | 2329 | const gpa = step.owner.allocator; |
| 2330 | | var br: std.io.Reader = .fixed(bytes); |
| 2330 | var r: std.io.Reader = .fixed(bytes); |
| 2331 | 2331 | |
| 2332 | | const buf = try br.takeArray(8); |
| 2332 | const buf = try r.takeArray(8); |
| 2333 | 2333 | if (!mem.eql(u8, buf[0..4], &std.wasm.magic)) return error.InvalidMagicByte; |
| 2334 | 2334 | if (!mem.eql(u8, buf[4..8], &std.wasm.version)) return error.UnsupportedWasmVersion; |
| 2335 | 2335 | |
| ... | ... | @@ -2337,7 +2337,7 @@ const WasmDumper = struct { |
| 2337 | 2337 | defer aw.deinit(); |
| 2338 | 2338 | const bw = &aw.writer; |
| 2339 | 2339 | |
| 2340 | | parseAndDumpInner(step, check, &br, bw) catch |err| switch (err) { |
| 2340 | parseAndDumpInner(step, check, &r, bw) catch |err| switch (err) { |
| 2341 | 2341 | error.EndOfStream => try bw.writeAll("\n<UnexpectedEndOfStream>"), |
| 2342 | 2342 | else => |e| return e, |
| 2343 | 2343 | }; |
| ... | ... | @@ -2347,14 +2347,13 @@ const WasmDumper = struct { |
| 2347 | 2347 | fn parseAndDumpInner( |
| 2348 | 2348 | step: *Step, |
| 2349 | 2349 | check: Check, |
| 2350 | | br: *std.io.Reader, |
| 2350 | r: *std.io.Reader, |
| 2351 | 2351 | bw: *Writer, |
| 2352 | 2352 | ) !void { |
| 2353 | | var section_br: std.io.Reader = undefined; |
| 2354 | 2353 | switch (check.kind) { |
| 2355 | | .headers => while (br.takeEnum(std.wasm.Section, .little)) |section| { |
| 2356 | | section_br = .fixed(try br.take(try br.takeLeb128(u32))); |
| 2357 | | try parseAndDumpSection(step, section, &section_br, bw); |
| 2354 | .headers => while (r.takeEnum(std.wasm.Section, .little)) |section| { |
| 2355 | var section_reader: std.io.Reader = .fixed(try r.take(try r.takeLeb128(u32))); |
| 2356 | try parseAndDumpSection(step, section, &section_reader, bw); |
| 2358 | 2357 | } else |err| switch (err) { |
| 2359 | 2358 | error.InvalidEnumTag => return step.fail("invalid section id", .{}), |
| 2360 | 2359 | error.EndOfStream => {}, |
| ... | ... | @@ -2367,13 +2366,13 @@ const WasmDumper = struct { |
| 2367 | 2366 | fn parseAndDumpSection( |
| 2368 | 2367 | step: *Step, |
| 2369 | 2368 | section: std.wasm.Section, |
| 2370 | | br: *std.io.Reader, |
| 2369 | r: *std.io.Reader, |
| 2371 | 2370 | bw: *Writer, |
| 2372 | 2371 | ) !void { |
| 2373 | 2372 | try bw.print( |
| 2374 | 2373 | \\Section {s} |
| 2375 | 2374 | \\size {d} |
| 2376 | | , .{ @tagName(section), br.buffer.len }); |
| 2375 | , .{ @tagName(section), r.buffer.len }); |
| 2377 | 2376 | |
| 2378 | 2377 | switch (section) { |
| 2379 | 2378 | .type, |
| ... | ... | @@ -2387,63 +2386,63 @@ const WasmDumper = struct { |
| 2387 | 2386 | .code, |
| 2388 | 2387 | .data, |
| 2389 | 2388 | => { |
| 2390 | | const entries = try br.takeLeb128(u32); |
| 2389 | const entries = try r.takeLeb128(u32); |
| 2391 | 2390 | try bw.print("\nentries {d}\n", .{entries}); |
| 2392 | | try parseSection(step, section, br, entries, bw); |
| 2391 | try parseSection(step, section, r, entries, bw); |
| 2393 | 2392 | }, |
| 2394 | 2393 | .custom => { |
| 2395 | | const name = try br.take(try br.takeLeb128(u32)); |
| 2394 | const name = try r.take(try r.takeLeb128(u32)); |
| 2396 | 2395 | try bw.print("\nname {s}\n", .{name}); |
| 2397 | 2396 | |
| 2398 | 2397 | if (mem.eql(u8, name, "name")) { |
| 2399 | | try parseDumpNames(step, br, bw); |
| 2398 | try parseDumpNames(step, r, bw); |
| 2400 | 2399 | } else if (mem.eql(u8, name, "producers")) { |
| 2401 | | try parseDumpProducers(br, bw); |
| 2400 | try parseDumpProducers(r, bw); |
| 2402 | 2401 | } else if (mem.eql(u8, name, "target_features")) { |
| 2403 | | try parseDumpFeatures(br, bw); |
| 2402 | try parseDumpFeatures(r, bw); |
| 2404 | 2403 | } |
| 2405 | 2404 | // TODO: Implement parsing and dumping other custom sections (such as relocations) |
| 2406 | 2405 | }, |
| 2407 | 2406 | .start => { |
| 2408 | | const start = try br.takeLeb128(u32); |
| 2407 | const start = try r.takeLeb128(u32); |
| 2409 | 2408 | try bw.print("\nstart {d}\n", .{start}); |
| 2410 | 2409 | }, |
| 2411 | 2410 | .data_count => { |
| 2412 | | const count = try br.takeLeb128(u32); |
| 2411 | const count = try r.takeLeb128(u32); |
| 2413 | 2412 | try bw.print("\ncount {d}\n", .{count}); |
| 2414 | 2413 | }, |
| 2415 | 2414 | else => {}, // skip unknown sections |
| 2416 | 2415 | } |
| 2417 | 2416 | } |
| 2418 | 2417 | |
| 2419 | | fn parseSection(step: *Step, section: std.wasm.Section, br: *std.io.Reader, entries: u32, bw: *Writer) !void { |
| 2418 | fn parseSection(step: *Step, section: std.wasm.Section, r: *std.io.Reader, entries: u32, bw: *Writer) !void { |
| 2420 | 2419 | switch (section) { |
| 2421 | 2420 | .type => { |
| 2422 | 2421 | var i: u32 = 0; |
| 2423 | 2422 | while (i < entries) : (i += 1) { |
| 2424 | | const func_type = try br.takeByte(); |
| 2423 | const func_type = try r.takeByte(); |
| 2425 | 2424 | if (func_type != std.wasm.function_type) { |
| 2426 | 2425 | return step.fail("expected function type, found byte '{d}'", .{func_type}); |
| 2427 | 2426 | } |
| 2428 | | const params = try br.takeLeb128(u32); |
| 2427 | const params = try r.takeLeb128(u32); |
| 2429 | 2428 | try bw.print("params {d}\n", .{params}); |
| 2430 | 2429 | var index: u32 = 0; |
| 2431 | 2430 | while (index < params) : (index += 1) { |
| 2432 | | _ = try parseDumpType(step, std.wasm.Valtype, br, bw); |
| 2431 | _ = try parseDumpType(step, std.wasm.Valtype, r, bw); |
| 2433 | 2432 | } else index = 0; |
| 2434 | | const returns = try br.takeLeb128(u32); |
| 2433 | const returns = try r.takeLeb128(u32); |
| 2435 | 2434 | try bw.print("returns {d}\n", .{returns}); |
| 2436 | 2435 | while (index < returns) : (index += 1) { |
| 2437 | | _ = try parseDumpType(step, std.wasm.Valtype, br, bw); |
| 2436 | _ = try parseDumpType(step, std.wasm.Valtype, r, bw); |
| 2438 | 2437 | } |
| 2439 | 2438 | } |
| 2440 | 2439 | }, |
| 2441 | 2440 | .import => { |
| 2442 | 2441 | var i: u32 = 0; |
| 2443 | 2442 | while (i < entries) : (i += 1) { |
| 2444 | | const module_name = try br.take(try br.takeLeb128(u32)); |
| 2445 | | const name = try br.take(try br.takeLeb128(u32)); |
| 2446 | | const kind = br.takeEnum(std.wasm.ExternalKind, .little) catch |err| switch (err) { |
| 2443 | const module_name = try r.take(try r.takeLeb128(u32)); |
| 2444 | const name = try r.take(try r.takeLeb128(u32)); |
| 2445 | const kind = r.takeEnum(std.wasm.ExternalKind, .little) catch |err| switch (err) { |
| 2447 | 2446 | error.InvalidEnumTag => return step.fail("invalid import kind", .{}), |
| 2448 | 2447 | else => |e| return e, |
| 2449 | 2448 | }; |
| ... | ... | @@ -2455,15 +2454,15 @@ const WasmDumper = struct { |
| 2455 | 2454 | , .{ module_name, name, @tagName(kind) }); |
| 2456 | 2455 | try bw.writeByte('\n'); |
| 2457 | 2456 | switch (kind) { |
| 2458 | | .function => try bw.print("index {d}\n", .{try br.takeLeb128(u32)}), |
| 2459 | | .memory => try parseDumpLimits(br, bw), |
| 2457 | .function => try bw.print("index {d}\n", .{try r.takeLeb128(u32)}), |
| 2458 | .memory => try parseDumpLimits(r, bw), |
| 2460 | 2459 | .global => { |
| 2461 | | _ = try parseDumpType(step, std.wasm.Valtype, br, bw); |
| 2462 | | try bw.print("mutable {}\n", .{0x01 == try br.takeLeb128(u32)}); |
| 2460 | _ = try parseDumpType(step, std.wasm.Valtype, r, bw); |
| 2461 | try bw.print("mutable {}\n", .{0x01 == try r.takeLeb128(u32)}); |
| 2463 | 2462 | }, |
| 2464 | 2463 | .table => { |
| 2465 | | _ = try parseDumpType(step, std.wasm.RefType, br, bw); |
| 2466 | | try parseDumpLimits(br, bw); |
| 2464 | _ = try parseDumpType(step, std.wasm.RefType, r, bw); |
| 2465 | try parseDumpLimits(r, bw); |
| 2467 | 2466 | }, |
| 2468 | 2467 | } |
| 2469 | 2468 | } |
| ... | ... | @@ -2471,39 +2470,39 @@ const WasmDumper = struct { |
| 2471 | 2470 | .function => { |
| 2472 | 2471 | var i: u32 = 0; |
| 2473 | 2472 | while (i < entries) : (i += 1) { |
| 2474 | | try bw.print("index {d}\n", .{try br.takeLeb128(u32)}); |
| 2473 | try bw.print("index {d}\n", .{try r.takeLeb128(u32)}); |
| 2475 | 2474 | } |
| 2476 | 2475 | }, |
| 2477 | 2476 | .table => { |
| 2478 | 2477 | var i: u32 = 0; |
| 2479 | 2478 | while (i < entries) : (i += 1) { |
| 2480 | | _ = try parseDumpType(step, std.wasm.RefType, br, bw); |
| 2481 | | try parseDumpLimits(br, bw); |
| 2479 | _ = try parseDumpType(step, std.wasm.RefType, r, bw); |
| 2480 | try parseDumpLimits(r, bw); |
| 2482 | 2481 | } |
| 2483 | 2482 | }, |
| 2484 | 2483 | .memory => { |
| 2485 | 2484 | var i: u32 = 0; |
| 2486 | 2485 | while (i < entries) : (i += 1) { |
| 2487 | | try parseDumpLimits(br, bw); |
| 2486 | try parseDumpLimits(r, bw); |
| 2488 | 2487 | } |
| 2489 | 2488 | }, |
| 2490 | 2489 | .global => { |
| 2491 | 2490 | var i: u32 = 0; |
| 2492 | 2491 | while (i < entries) : (i += 1) { |
| 2493 | | _ = try parseDumpType(step, std.wasm.Valtype, br, bw); |
| 2494 | | try bw.print("mutable {}\n", .{0x01 == try br.takeLeb128(u1)}); |
| 2495 | | try parseDumpInit(step, br, bw); |
| 2492 | _ = try parseDumpType(step, std.wasm.Valtype, r, bw); |
| 2493 | try bw.print("mutable {}\n", .{0x01 == try r.takeLeb128(u1)}); |
| 2494 | try parseDumpInit(step, r, bw); |
| 2496 | 2495 | } |
| 2497 | 2496 | }, |
| 2498 | 2497 | .@"export" => { |
| 2499 | 2498 | var i: u32 = 0; |
| 2500 | 2499 | while (i < entries) : (i += 1) { |
| 2501 | | const name = try br.take(try br.takeLeb128(u32)); |
| 2502 | | const kind = br.takeEnum(std.wasm.ExternalKind, .little) catch |err| switch (err) { |
| 2500 | const name = try r.take(try r.takeLeb128(u32)); |
| 2501 | const kind = r.takeEnum(std.wasm.ExternalKind, .little) catch |err| switch (err) { |
| 2503 | 2502 | error.InvalidEnumTag => return step.fail("invalid export kind value", .{}), |
| 2504 | 2503 | else => |e| return e, |
| 2505 | 2504 | }; |
| 2506 | | const index = try br.takeLeb128(u32); |
| 2505 | const index = try r.takeLeb128(u32); |
| 2507 | 2506 | try bw.print( |
| 2508 | 2507 | \\name {s} |
| 2509 | 2508 | \\kind {s} |
| ... | ... | @@ -2515,14 +2514,14 @@ const WasmDumper = struct { |
| 2515 | 2514 | .element => { |
| 2516 | 2515 | var i: u32 = 0; |
| 2517 | 2516 | while (i < entries) : (i += 1) { |
| 2518 | | try bw.print("table index {d}\n", .{try br.takeLeb128(u32)}); |
| 2519 | | try parseDumpInit(step, br, bw); |
| 2517 | try bw.print("table index {d}\n", .{try r.takeLeb128(u32)}); |
| 2518 | try parseDumpInit(step, r, bw); |
| 2520 | 2519 | |
| 2521 | | const function_indexes = try br.takeLeb128(u32); |
| 2520 | const function_indexes = try r.takeLeb128(u32); |
| 2522 | 2521 | var function_index: u32 = 0; |
| 2523 | 2522 | try bw.print("indexes {d}\n", .{function_indexes}); |
| 2524 | 2523 | while (function_index < function_indexes) : (function_index += 1) { |
| 2525 | | try bw.print("index {d}\n", .{try br.takeLeb128(u32)}); |
| 2524 | try bw.print("index {d}\n", .{try r.takeLeb128(u32)}); |
| 2526 | 2525 | } |
| 2527 | 2526 | } |
| 2528 | 2527 | }, |
| ... | ... | @@ -2534,21 +2533,21 @@ const WasmDumper = struct { |
| 2534 | 2533 | passive: bool, |
| 2535 | 2534 | memidx: bool, |
| 2536 | 2535 | unused: u30, |
| 2537 | | } = @bitCast(try br.takeLeb128(u32)); |
| 2538 | | const index = if (flags.memidx) try br.takeLeb128(u32) else 0; |
| 2536 | } = @bitCast(try r.takeLeb128(u32)); |
| 2537 | const index = if (flags.memidx) try r.takeLeb128(u32) else 0; |
| 2539 | 2538 | try bw.print("memory index 0x{x}\n", .{index}); |
| 2540 | | if (!flags.passive) try parseDumpInit(step, br, bw); |
| 2541 | | const size = try br.takeLeb128(u32); |
| 2539 | if (!flags.passive) try parseDumpInit(step, r, bw); |
| 2540 | const size = try r.takeLeb128(u32); |
| 2542 | 2541 | try bw.print("size {d}\n", .{size}); |
| 2543 | | _ = try br.discard(.limited(size)); // we do not care about the content of the segments |
| 2542 | _ = try r.discard(.limited(size)); // we do not care about the content of the segments |
| 2544 | 2543 | } |
| 2545 | 2544 | }, |
| 2546 | 2545 | else => unreachable, |
| 2547 | 2546 | } |
| 2548 | 2547 | } |
| 2549 | 2548 | |
| 2550 | | fn parseDumpType(step: *Step, comptime E: type, br: *std.io.Reader, bw: *Writer) !E { |
| 2551 | | const tag = br.takeEnum(E, .little) catch |err| switch (err) { |
| 2549 | fn parseDumpType(step: *Step, comptime E: type, r: *std.io.Reader, bw: *Writer) !E { |
| 2550 | const tag = r.takeEnum(E, .little) catch |err| switch (err) { |
| 2552 | 2551 | error.InvalidEnumTag => return step.fail("invalid wasm type value", .{}), |
| 2553 | 2552 | else => |e| return e, |
| 2554 | 2553 | }; |
| ... | ... | @@ -2556,42 +2555,42 @@ const WasmDumper = struct { |
| 2556 | 2555 | return tag; |
| 2557 | 2556 | } |
| 2558 | 2557 | |
| 2559 | | fn parseDumpLimits(br: *std.io.Reader, bw: *Writer) !void { |
| 2560 | | const flags = try br.takeLeb128(u8); |
| 2561 | | const min = try br.takeLeb128(u32); |
| 2558 | fn parseDumpLimits(r: *std.io.Reader, bw: *Writer) !void { |
| 2559 | const flags = try r.takeLeb128(u8); |
| 2560 | const min = try r.takeLeb128(u32); |
| 2562 | 2561 | |
| 2563 | 2562 | try bw.print("min {x}\n", .{min}); |
| 2564 | | if (flags != 0) try bw.print("max {x}\n", .{try br.takeLeb128(u32)}); |
| 2563 | if (flags != 0) try bw.print("max {x}\n", .{try r.takeLeb128(u32)}); |
| 2565 | 2564 | } |
| 2566 | 2565 | |
| 2567 | | fn parseDumpInit(step: *Step, br: *std.io.Reader, bw: *Writer) !void { |
| 2568 | | const opcode = br.takeEnum(std.wasm.Opcode, .little) catch |err| switch (err) { |
| 2566 | fn parseDumpInit(step: *Step, r: *std.io.Reader, bw: *Writer) !void { |
| 2567 | const opcode = r.takeEnum(std.wasm.Opcode, .little) catch |err| switch (err) { |
| 2569 | 2568 | error.InvalidEnumTag => return step.fail("invalid wasm opcode", .{}), |
| 2570 | 2569 | else => |e| return e, |
| 2571 | 2570 | }; |
| 2572 | 2571 | switch (opcode) { |
| 2573 | | .i32_const => try bw.print("i32.const {x}\n", .{try br.takeLeb128(i32)}), |
| 2574 | | .i64_const => try bw.print("i64.const {x}\n", .{try br.takeLeb128(i64)}), |
| 2575 | | .f32_const => try bw.print("f32.const {x}\n", .{@as(f32, @bitCast(try br.takeInt(u32, .little)))}), |
| 2576 | | .f64_const => try bw.print("f64.const {x}\n", .{@as(f64, @bitCast(try br.takeInt(u64, .little)))}), |
| 2577 | | .global_get => try bw.print("global.get {x}\n", .{try br.takeLeb128(u32)}), |
| 2572 | .i32_const => try bw.print("i32.const {x}\n", .{try r.takeLeb128(i32)}), |
| 2573 | .i64_const => try bw.print("i64.const {x}\n", .{try r.takeLeb128(i64)}), |
| 2574 | .f32_const => try bw.print("f32.const {x}\n", .{@as(f32, @bitCast(try r.takeInt(u32, .little)))}), |
| 2575 | .f64_const => try bw.print("f64.const {x}\n", .{@as(f64, @bitCast(try r.takeInt(u64, .little)))}), |
| 2576 | .global_get => try bw.print("global.get {x}\n", .{try r.takeLeb128(u32)}), |
| 2578 | 2577 | else => unreachable, |
| 2579 | 2578 | } |
| 2580 | | const end_opcode = try br.takeLeb128(u8); |
| 2579 | const end_opcode = try r.takeLeb128(u8); |
| 2581 | 2580 | if (end_opcode != @intFromEnum(std.wasm.Opcode.end)) { |
| 2582 | 2581 | return step.fail("expected 'end' opcode in init expression", .{}); |
| 2583 | 2582 | } |
| 2584 | 2583 | } |
| 2585 | 2584 | |
| 2586 | 2585 | /// https://webassembly.github.io/spec/core/appendix/custom.html |
| 2587 | | fn parseDumpNames(step: *Step, br: *std.io.Reader, bw: *Writer) !void { |
| 2586 | fn parseDumpNames(step: *Step, r: *std.io.Reader, bw: *Writer) !void { |
| 2588 | 2587 | var subsection_br: std.io.Reader = undefined; |
| 2589 | | while (br.seek < br.buffer.len) { |
| 2590 | | switch (try parseDumpType(step, std.wasm.NameSubsection, br, bw)) { |
| 2588 | while (r.seek < r.buffer.len) { |
| 2589 | switch (try parseDumpType(step, std.wasm.NameSubsection, r, bw)) { |
| 2591 | 2590 | // The module name subsection ... consists of a single name |
| 2592 | 2591 | // that is assigned to the module itself. |
| 2593 | 2592 | .module => { |
| 2594 | | subsection_br = .fixed(try br.take(try br.takeLeb128(u32))); |
| 2593 | subsection_br = .fixed(try r.take(try r.takeLeb128(u32))); |
| 2595 | 2594 | const name = try subsection_br.take(try subsection_br.takeLeb128(u32)); |
| 2596 | 2595 | try bw.print( |
| 2597 | 2596 | \\name {s} |
| ... | ... | @@ -2603,15 +2602,15 @@ const WasmDumper = struct { |
| 2603 | 2602 | // The function name subsection ... consists of a name map |
| 2604 | 2603 | // assigning function names to function indices. |
| 2605 | 2604 | .function, .global, .data_segment => { |
| 2606 | | subsection_br = .fixed(try br.take(try br.takeLeb128(u32))); |
| 2607 | | const entries = try br.takeLeb128(u32); |
| 2605 | subsection_br = .fixed(try r.take(try r.takeLeb128(u32))); |
| 2606 | const entries = try r.takeLeb128(u32); |
| 2608 | 2607 | try bw.print( |
| 2609 | 2608 | \\names {d} |
| 2610 | 2609 | \\ |
| 2611 | 2610 | , .{entries}); |
| 2612 | 2611 | for (0..entries) |_| { |
| 2613 | | const index = try br.takeLeb128(u32); |
| 2614 | | const name = try br.take(try br.takeLeb128(u32)); |
| 2612 | const index = try r.takeLeb128(u32); |
| 2613 | const name = try r.take(try r.takeLeb128(u32)); |
| 2615 | 2614 | try bw.print( |
| 2616 | 2615 | \\index {d} |
| 2617 | 2616 | \\name {s} |
| ... | ... | @@ -2633,16 +2632,16 @@ const WasmDumper = struct { |
| 2633 | 2632 | } |
| 2634 | 2633 | } |
| 2635 | 2634 | |
| 2636 | | fn parseDumpProducers(br: *std.io.Reader, bw: *Writer) !void { |
| 2637 | | const field_count = try br.takeLeb128(u32); |
| 2635 | fn parseDumpProducers(r: *std.io.Reader, bw: *Writer) !void { |
| 2636 | const field_count = try r.takeLeb128(u32); |
| 2638 | 2637 | try bw.print( |
| 2639 | 2638 | \\fields {d} |
| 2640 | 2639 | \\ |
| 2641 | 2640 | , .{field_count}); |
| 2642 | 2641 | var current_field: u32 = 0; |
| 2643 | 2642 | while (current_field < field_count) : (current_field += 1) { |
| 2644 | | const field_name = try br.take(try br.takeLeb128(u32)); |
| 2645 | | const value_count = try br.takeLeb128(u32); |
| 2643 | const field_name = try r.take(try r.takeLeb128(u32)); |
| 2644 | const value_count = try r.takeLeb128(u32); |
| 2646 | 2645 | try bw.print( |
| 2647 | 2646 | \\field_name {s} |
| 2648 | 2647 | \\values {d} |
| ... | ... | @@ -2650,8 +2649,8 @@ const WasmDumper = struct { |
| 2650 | 2649 | , .{ field_name, value_count }); |
| 2651 | 2650 | var current_value: u32 = 0; |
| 2652 | 2651 | while (current_value < value_count) : (current_value += 1) { |
| 2653 | | const value = try br.take(try br.takeLeb128(u32)); |
| 2654 | | const version = try br.take(try br.takeLeb128(u32)); |
| 2652 | const value = try r.take(try r.takeLeb128(u32)); |
| 2653 | const version = try r.take(try r.takeLeb128(u32)); |
| 2655 | 2654 | try bw.print( |
| 2656 | 2655 | \\value_name {s} |
| 2657 | 2656 | \\version {s} |
| ... | ... | @@ -2661,8 +2660,8 @@ const WasmDumper = struct { |
| 2661 | 2660 | } |
| 2662 | 2661 | } |
| 2663 | 2662 | |
| 2664 | | fn parseDumpFeatures(br: *std.io.Reader, bw: *Writer) !void { |
| 2665 | | const feature_count = try br.takeLeb128(u32); |
| 2663 | fn parseDumpFeatures(r: *std.io.Reader, bw: *Writer) !void { |
| 2664 | const feature_count = try r.takeLeb128(u32); |
| 2666 | 2665 | try bw.print( |
| 2667 | 2666 | \\features {d} |
| 2668 | 2667 | \\ |
| ... | ... | @@ -2670,8 +2669,8 @@ const WasmDumper = struct { |
| 2670 | 2669 | |
| 2671 | 2670 | var index: u32 = 0; |
| 2672 | 2671 | while (index < feature_count) : (index += 1) { |
| 2673 | | const prefix_byte = try br.takeLeb128(u8); |
| 2674 | | const feature_name = try br.take(try br.takeLeb128(u32)); |
| 2672 | const prefix_byte = try r.takeLeb128(u8); |
| 2673 | const feature_name = try r.take(try r.takeLeb128(u32)); |
| 2675 | 2674 | try bw.print( |
| 2676 | 2675 | \\{c} {s} |
| 2677 | 2676 | \\ |