Skip to content

Commit a69788b

Browse files
committed
std.Build.Step.CheckObject: fix parseDumpNames
This function incorrectly assumed that module name subsections, function name subsections, and local name subsections are encoded the same, however according to [the specification](https://webassembly.github.io/spec/core/appendix/custom.html) they are encoded differently. This commit adds support for parsing module name subsections correctly, which started appearing after upgrading to LLVM 18.
1 parent 1c9bb6a commit a69788b

File tree

1 file changed

+57
-31
lines changed

1 file changed

+57
-31
lines changed

lib/std/Build/Step/CheckObject.zig

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2475,12 +2475,12 @@ const WasmDumper = struct {
24752475
try writer.print("params {d}\n", .{params});
24762476
var index: u32 = 0;
24772477
while (index < params) : (index += 1) {
2478-
try parseDumpType(step, std.wasm.Valtype, reader, writer);
2478+
_ = try parseDumpType(step, std.wasm.Valtype, reader, writer);
24792479
} else index = 0;
24802480
const returns = try std.leb.readULEB128(u32, reader);
24812481
try writer.print("returns {d}\n", .{returns});
24822482
while (index < returns) : (index += 1) {
2483-
try parseDumpType(step, std.wasm.Valtype, reader, writer);
2483+
_ = try parseDumpType(step, std.wasm.Valtype, reader, writer);
24842484
}
24852485
}
24862486
},
@@ -2512,11 +2512,11 @@ const WasmDumper = struct {
25122512
try parseDumpLimits(reader, writer);
25132513
},
25142514
.global => {
2515-
try parseDumpType(step, std.wasm.Valtype, reader, writer);
2515+
_ = try parseDumpType(step, std.wasm.Valtype, reader, writer);
25162516
try writer.print("mutable {}\n", .{0x01 == try std.leb.readULEB128(u32, reader)});
25172517
},
25182518
.table => {
2519-
try parseDumpType(step, std.wasm.RefType, reader, writer);
2519+
_ = try parseDumpType(step, std.wasm.RefType, reader, writer);
25202520
try parseDumpLimits(reader, writer);
25212521
},
25222522
}
@@ -2531,7 +2531,7 @@ const WasmDumper = struct {
25312531
.table => {
25322532
var i: u32 = 0;
25332533
while (i < entries) : (i += 1) {
2534-
try parseDumpType(step, std.wasm.RefType, reader, writer);
2534+
_ = try parseDumpType(step, std.wasm.RefType, reader, writer);
25352535
try parseDumpLimits(reader, writer);
25362536
}
25372537
},
@@ -2544,7 +2544,7 @@ const WasmDumper = struct {
25442544
.global => {
25452545
var i: u32 = 0;
25462546
while (i < entries) : (i += 1) {
2547-
try parseDumpType(step, std.wasm.Valtype, reader, writer);
2547+
_ = try parseDumpType(step, std.wasm.Valtype, reader, writer);
25482548
try writer.print("mutable {}\n", .{0x01 == try std.leb.readULEB128(u1, reader)});
25492549
try parseDumpInit(step, reader, writer);
25502550
}
@@ -2605,12 +2605,13 @@ const WasmDumper = struct {
26052605
}
26062606
}
26072607

2608-
fn parseDumpType(step: *Step, comptime WasmType: type, reader: anytype, writer: anytype) !void {
2609-
const type_byte = try reader.readByte();
2610-
const valtype = std.meta.intToEnum(WasmType, type_byte) catch {
2611-
return step.fail("Invalid wasm type value '{d}'", .{type_byte});
2608+
fn parseDumpType(step: *Step, comptime E: type, reader: anytype, writer: anytype) !E {
2609+
const byte = try reader.readByte();
2610+
const tag = std.meta.intToEnum(E, byte) catch {
2611+
return step.fail("invalid wasm type value '{d}'", .{byte});
26122612
};
2613-
try writer.print("type {s}\n", .{@tagName(valtype)});
2613+
try writer.print("type {s}\n", .{@tagName(tag)});
2614+
return tag;
26142615
}
26152616

26162617
fn parseDumpLimits(reader: anytype, writer: anytype) !void {
@@ -2642,29 +2643,54 @@ const WasmDumper = struct {
26422643
}
26432644
}
26442645

2646+
/// https://webassembly.github.io/spec/core/appendix/custom.html
26452647
fn parseDumpNames(step: *Step, reader: anytype, writer: anytype, data: []const u8) !void {
26462648
while (reader.context.pos < data.len) {
2647-
try parseDumpType(step, std.wasm.NameSubsection, reader, writer);
2648-
const size = try std.leb.readULEB128(u32, reader);
2649-
const entries = try std.leb.readULEB128(u32, reader);
2650-
try writer.print(
2651-
\\size {d}
2652-
\\names {d}
2653-
, .{ size, entries });
2654-
try writer.writeByte('\n');
2655-
var i: u32 = 0;
2656-
while (i < entries) : (i += 1) {
2657-
const index = try std.leb.readULEB128(u32, reader);
2658-
const name_len = try std.leb.readULEB128(u32, reader);
2659-
const pos = reader.context.pos;
2660-
const name = data[pos..][0..name_len];
2661-
reader.context.pos += name_len;
2649+
switch (try parseDumpType(step, std.wasm.NameSubsection, reader, writer)) {
2650+
// The module name subsection ... consists of a single name
2651+
// that is assigned to the module itself.
2652+
.module => {
2653+
const size = try std.leb.readULEB128(u32, reader);
2654+
const name_len = try std.leb.readULEB128(u32, reader);
2655+
if (size != name_len + 1) return error.BadSubsectionSize;
2656+
if (reader.context.pos + name_len > data.len) return error.UnexpectedEndOfStream;
2657+
try writer.print("name {s}\n", .{data[reader.context.pos..][0..name_len]});
2658+
reader.context.pos += name_len;
2659+
},
26622660

2663-
try writer.print(
2664-
\\index {d}
2665-
\\name {s}
2666-
, .{ index, name });
2667-
try writer.writeByte('\n');
2661+
// The function name subsection ... consists of a name map
2662+
// assigning function names to function indices.
2663+
.function, .global, .data_segment => {
2664+
const size = try std.leb.readULEB128(u32, reader);
2665+
const entries = try std.leb.readULEB128(u32, reader);
2666+
try writer.print(
2667+
\\size {d}
2668+
\\names {d}
2669+
\\
2670+
, .{ size, entries });
2671+
for (0..entries) |_| {
2672+
const index = try std.leb.readULEB128(u32, reader);
2673+
const name_len = try std.leb.readULEB128(u32, reader);
2674+
if (reader.context.pos + name_len > data.len) return error.UnexpectedEndOfStream;
2675+
const name = data[reader.context.pos..][0..name_len];
2676+
reader.context.pos += name.len;
2677+
2678+
try writer.print(
2679+
\\index {d}
2680+
\\name {s}
2681+
\\
2682+
, .{ index, name });
2683+
}
2684+
},
2685+
2686+
// The local name subsection ... consists of an indirect name
2687+
// map assigning local names to local indices grouped by
2688+
// function indices.
2689+
.local => {
2690+
return step.fail("TODO implement parseDumpNames for local subsections", .{});
2691+
},
2692+
2693+
else => |t| return step.fail("invalid subsection type: {s}", .{@tagName(t)}),
26682694
}
26692695
}
26702696
}

0 commit comments

Comments
 (0)