Skip to content

Commit 984f7f3

Browse files
authored
[cpp20] Modernize binary reader and writer APIs to use std::span (WebAssembly#2775)
Replace legacy raw pointer and size pairs with std::span<const uint8_t> (aliased to `ByteSpan`) across WABT's binary reader interfaces, writer streams, parser callbacks, and public entry points. This greatly improves type safety, simplifies call sites (allowing vectors and arrays to be passed directly), and aligns WABT with modern C++20 standards. Highlights: - Fixes a performance bug in Stream::WriteData where passing std::vector accidentally triggered a full copy-by-value of the vector's contents. The template overload now correctly accepts std::span (zero-copy). - Simplifies various writing call sites (e.g. in binary-writer, c-writer, and wasm-strip) by passing vectors directly or leveraging subspan.
1 parent 23b62e9 commit 984f7f3

38 files changed

Lines changed: 236 additions & 269 deletions

fuzzers/read_binary_interp_fuzzer.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
4040
// validator's counts out of step).
4141
wabt::ReadBinaryOptions options(features, nullptr, false, true, false);
4242
std::vector<uint8_t> text = data_provider.ConsumeRemainingBytes<uint8_t>();
43-
ReadBinaryInterp("<fuzzer>", text.data(), text.size(), options, &errors,
44-
&module);
43+
ReadBinaryInterp("<fuzzer>", text, options, &errors, &module);
4544
return 0;
4645
}

fuzzers/read_binary_ir_fuzzer.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
3434
// Add only feature related options, but no logging, stop_on_first_error, etc.
3535
wabt::ReadBinaryOptions options(features, nullptr, false, false, false);
3636
std::vector<uint8_t> text = data_provider.ConsumeRemainingBytes<uint8_t>();
37-
ReadBinaryIr("", text.data(), text.size(), options, &errors, &module);
37+
ReadBinaryIr("", text, options, &errors, &module);
3838
return 0;
3939
}

fuzzers/wasm2wat_fuzzer.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
2121
wabt::ReadBinaryOptions options;
2222
wabt::Errors errors;
2323
wabt::Module module;
24-
wabt::ReadBinaryIr("dummy filename", data, size, options, &errors, &module);
24+
wabt::ReadBinaryIr("dummy filename", {data, size}, options, &errors, &module);
2525
return 0;
2626
}

fuzzers/wasm_objdump_fuzzer.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
2424
objdump_options.log_stream = nullptr;
2525

2626
objdump_options.mode = wabt::ObjdumpMode::Prepass;
27-
wabt::ReadBinaryObjdump(data, size, &objdump_options, &state);
27+
wabt::ReadBinaryObjdump({data, size}, &objdump_options, &state);
2828

2929
objdump_options.mode = wabt::ObjdumpMode::Headers;
30-
wabt::ReadBinaryObjdump(data, size, &objdump_options, &state);
30+
wabt::ReadBinaryObjdump({data, size}, &objdump_options, &state);
3131

3232
objdump_options.mode = wabt::ObjdumpMode::Details;
33-
wabt::ReadBinaryObjdump(data, size, &objdump_options, &state);
33+
wabt::ReadBinaryObjdump({data, size}, &objdump_options, &state);
3434

3535
objdump_options.mode = wabt::ObjdumpMode::Disassemble;
36-
wabt::ReadBinaryObjdump(data, size, &objdump_options, &state);
36+
wabt::ReadBinaryObjdump({data, size}, &objdump_options, &state);
3737

3838
objdump_options.mode = wabt::ObjdumpMode::RawData;
39-
wabt::ReadBinaryObjdump(data, size, &objdump_options, &state);
39+
wabt::ReadBinaryObjdump({data, size}, &objdump_options, &state);
4040

4141
return 0;
4242
}

include/wabt/base-types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919

2020
#include <cstddef>
2121
#include <cstdint>
22+
#include <span>
2223

2324
namespace wabt {
2425

2526
using Index = uint32_t; // An index into one of the many index spaces.
2627
using Address = uint64_t; // An address or size in linear memory.
2728
using Offset = size_t; // An offset into a host's file or memory buffer.
29+
using ByteSpan = std::span<const uint8_t>;
2830

2931
constexpr Address kInvalidAddress = ~0;
3032
constexpr Index kInvalidIndex = ~0;

include/wabt/binary-reader-ir.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,14 @@ struct Module;
2626
struct ReadBinaryOptions;
2727

2828
Result ReadBinaryIr(const char* filename,
29-
const void* data,
29+
ByteSpan data,
30+
const ReadBinaryOptions& options,
31+
Errors*,
32+
Module* out_module);
33+
34+
// TODO(sbc): Remove this old API. Use the ByteSpan overload instead.
35+
Result ReadBinaryIr(const char* filename,
36+
const uint8_t* data,
3037
size_t size,
3138
const ReadBinaryOptions& options,
3239
Errors*,

include/wabt/binary-reader-logging.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,7 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
303303
uint8_t flags) override;
304304
Result BeginDataSegmentInitExpr(Index index) override;
305305
Result EndDataSegmentInitExpr(Index index) override;
306-
Result OnDataSegmentData(Index index,
307-
const void* data,
308-
Address size) override;
306+
Result OnDataSegmentData(Index index, ByteSpan data) override;
309307
Result EndDataSegment(Index index) override;
310308
Result EndDataSection() override;
311309

@@ -365,9 +363,7 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
365363
Result EndDylinkSection() override;
366364

367365
Result BeginGenericCustomSection(Offset size) override;
368-
Result OnGenericCustomSection(std::string_view name,
369-
const void* data,
370-
Offset size) override;
366+
Result OnGenericCustomSection(std::string_view name, ByteSpan data) override;
371367
Result EndGenericCustomSection() override;
372368

373369
Result BeginTargetFeaturesSection(Offset size) override;
@@ -425,7 +421,7 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
425421
Result BeginCodeMetadataSection(std::string_view name, Offset size) override;
426422
Result OnCodeMetadataFuncCount(Index count) override;
427423
Result OnCodeMetadataCount(Index function_index, Index count) override;
428-
Result OnCodeMetadata(Offset offset, const void* data, Address size) override;
424+
Result OnCodeMetadata(Offset offset, ByteSpan data) override;
429425
Result EndCodeMetadataSection() override;
430426

431427
private:

include/wabt/binary-reader-nop.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -409,9 +409,7 @@ class BinaryReaderNop : public BinaryReaderDelegate {
409409
}
410410
Result BeginDataSegmentInitExpr(Index index) override { return Result::Ok; }
411411
Result EndDataSegmentInitExpr(Index index) override { return Result::Ok; }
412-
Result OnDataSegmentData(Index index,
413-
const void* data,
414-
Address size) override {
412+
Result OnDataSegmentData(Index index, ByteSpan data) override {
415413
return Result::Ok;
416414
}
417415
Result EndDataSegment(Index index) override { return Result::Ok; }
@@ -500,9 +498,7 @@ class BinaryReaderNop : public BinaryReaderDelegate {
500498
Result OnCodeMetadataCount(Index function_index, Index count) override {
501499
return Result::Ok;
502500
}
503-
Result OnCodeMetadata(Offset offset,
504-
const void* data,
505-
Address size) override {
501+
Result OnCodeMetadata(Offset offset, ByteSpan data) override {
506502
return Result::Ok;
507503
}
508504
Result EndCodeMetadataSection() override { return Result::Ok; }
@@ -541,9 +537,7 @@ class BinaryReaderNop : public BinaryReaderDelegate {
541537

542538
/* Generic custom section */
543539
Result BeginGenericCustomSection(Offset size) override { return Result::Ok; }
544-
Result OnGenericCustomSection(std::string_view name,
545-
const void* data,
546-
Offset size) override {
540+
Result OnGenericCustomSection(std::string_view name, ByteSpan data) override {
547541
return Result::Ok;
548542
};
549543
Result EndGenericCustomSection() override { return Result::Ok; }

include/wabt/binary-reader-objdump.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ struct ObjdumpState {
8989
std::map<Index, Index> function_types;
9090
};
9191

92+
Result ReadBinaryObjdump(ByteSpan data,
93+
ObjdumpOptions* options,
94+
ObjdumpState* state);
95+
96+
// TODO(sbc): Remove this old API. Use the ByteSpan overload instead.
9297
Result ReadBinaryObjdump(const uint8_t* data,
9398
size_t size,
9499
ObjdumpOptions* options,

include/wabt/binary-reader-stats.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ bool operator>=(const OpcodeInfo&, const OpcodeInfo&);
8686

8787
using OpcodeInfoCounts = std::map<OpcodeInfo, size_t>;
8888

89-
Result ReadBinaryOpcnt(const void* data,
90-
size_t size,
89+
Result ReadBinaryOpcnt(ByteSpan data,
9190
const ReadBinaryOptions& options,
9291
OpcodeInfoCounts* opcode_counts);
9392

0 commit comments

Comments
 (0)