summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binary-reader-logging.cc4
-rw-r--r--src/binary-reader-logging.h4
-rw-r--r--src/binary-reader-nop.h5
-rw-r--r--src/binary-reader-objdump.cc15
-rw-r--r--src/binary-reader.cc33
-rw-r--r--src/binary-reader.h5
-rw-r--r--src/binary-writer.cc6
-rw-r--r--src/binary-writer.h12
-rw-r--r--src/binary.cc24
-rw-r--r--src/binary.h21
-rw-r--r--src/tools/wast2json.cc1
-rw-r--r--src/tools/wat2wasm.cc1
12 files changed, 111 insertions, 20 deletions
diff --git a/src/binary-reader-logging.cc b/src/binary-reader-logging.cc
index bb89fb9d..9a383584 100644
--- a/src/binary-reader-logging.cc
+++ b/src/binary-reader-logging.cc
@@ -738,6 +738,10 @@ DEFINE_INDEX(EndDataSegmentInitExpr)
DEFINE_INDEX(EndDataSegment)
DEFINE_END(EndDataSection)
+DEFINE_BEGIN(BeginDataCountSection)
+DEFINE_INDEX(OnDataCount)
+DEFINE_END(EndDataCountSection)
+
DEFINE_BEGIN(BeginNamesSection)
DEFINE_INDEX(OnFunctionNamesCount)
DEFINE_INDEX(OnLocalNameFunctionCount)
diff --git a/src/binary-reader-logging.h b/src/binary-reader-logging.h
index 0f2c509a..edb6132e 100644
--- a/src/binary-reader-logging.h
+++ b/src/binary-reader-logging.h
@@ -233,6 +233,10 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
Result EndDataSegment(Index index) override;
Result EndDataSection() override;
+ Result BeginDataCountSection(Offset size) override;
+ Result OnDataCount(Index count) override;
+ Result EndDataCountSection() override;
+
Result BeginNamesSection(Offset size) override;
Result OnModuleNameSubsection(Index index,
uint32_t name_type,
diff --git a/src/binary-reader-nop.h b/src/binary-reader-nop.h
index bfab11d8..20ac7158 100644
--- a/src/binary-reader-nop.h
+++ b/src/binary-reader-nop.h
@@ -307,6 +307,11 @@ class BinaryReaderNop : public BinaryReaderDelegate {
Result EndDataSegment(Index index) override { return Result::Ok; }
Result EndDataSection() override { return Result::Ok; }
+ /* DataCount section */
+ Result BeginDataCountSection(Offset size) override { return Result::Ok; }
+ Result OnDataCount(Index count) override { return Result::Ok; }
+ Result EndDataCountSection() override { return Result::Ok; }
+
/* Names section */
Result BeginNamesSection(Offset size) override { return Result::Ok; }
Result OnModuleNameSubsection(Index index,
diff --git a/src/binary-reader-objdump.cc b/src/binary-reader-objdump.cc
index 94ed487d..64cdaef0 100644
--- a/src/binary-reader-objdump.cc
+++ b/src/binary-reader-objdump.cc
@@ -717,6 +717,7 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase {
string_view name) override;
Result OnStartFunction(Index func_index) override;
+ Result OnDataCount(Index count) override;
Result OnFunctionBodyCount(Index count) override;
Result BeginFunctionBody(Index index, Offset size) override;
@@ -866,9 +867,10 @@ Result BinaryReaderObjdump::BeginSection(BinarySection section_code,
case ObjdumpMode::Details:
if (section_match) {
printf("%s", name);
- // All known section types except the start section have a count
- // in which case this line gets completed in OnCount().
+ // All known section types except the Start and DataCount sections have
+ // a count in which case this line gets completed in OnCount().
if (section_code == BinarySection::Start ||
+ section_code == BinarySection::DataCount ||
section_code == BinarySection::Custom) {
printf(":\n");
}
@@ -994,6 +996,15 @@ Result BinaryReaderObjdump::OnStartFunction(Index func_index) {
return Result::Ok;
}
+Result BinaryReaderObjdump::OnDataCount(Index count) {
+ if (options_->mode == ObjdumpMode::Headers) {
+ printf("count: %" PRIindex "\n", count);
+ } else {
+ PrintDetails(" - data count: %" PRIindex "\n", count);
+ }
+ return Result::Ok;
+}
+
Result BinaryReaderObjdump::OnImportCount(Index count) {
return OnCount(count);
}
diff --git a/src/binary-reader.cc b/src/binary-reader.cc
index 089927cc..c01216e4 100644
--- a/src/binary-reader.cc
+++ b/src/binary-reader.cc
@@ -137,6 +137,7 @@ class BinaryReader {
Result ReadElemSection(Offset section_size) WABT_WARN_UNUSED;
Result ReadCodeSection(Offset section_size) WABT_WARN_UNUSED;
Result ReadDataSection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadDataCountSection(Offset section_size) WABT_WARN_UNUSED;
Result ReadExceptionSection(Offset section_size) WABT_WARN_UNUSED;
Result ReadSections() WABT_WARN_UNUSED;
Result ReportUnexpectedOpcode(Opcode opcode, const char* message = nullptr);
@@ -166,6 +167,7 @@ class BinaryReader {
Index num_exports_ = 0;
Index num_function_bodies_ = 0;
Index num_exceptions_ = 0;
+ Index data_count_ = kInvalidIndex;
using ReadEndRestoreGuard =
ValueRestoreGuard<size_t, &BinaryReader::read_end_>;
@@ -2071,6 +2073,9 @@ Result BinaryReader::ReadDataSection(Offset section_size) {
CALLBACK(OnDataSegmentCount, num_data_segments);
ERROR_UNLESS(num_data_segments == 0 || NumTotalMemories() > 0,
"data section without memory section");
+ // If the DataCount section is not present, then data_count_ will be invalid.
+ ERROR_UNLESS(data_count_ == kInvalidIndex || data_count_ == num_data_segments,
+ "data segment count does not equal count in DataCount section");
for (Index i = 0; i < num_data_segments; ++i) {
uint32_t flags_u32;
CHECK_RESULT(ReadU32Leb128(&flags_u32, "data segment flags"));
@@ -2098,6 +2103,16 @@ Result BinaryReader::ReadDataSection(Offset section_size) {
return Result::Ok;
}
+Result BinaryReader::ReadDataCountSection(Offset section_size) {
+ CALLBACK(BeginDataCountSection, section_size);
+ Index data_count;
+ CHECK_RESULT(ReadIndex(&data_count, "data count"));
+ CALLBACK(OnDataCount, data_count);
+ CALLBACK0(EndDataCountSection);
+ data_count_ = data_count;
+ return Result::Ok;
+}
+
Result BinaryReader::ReadSections() {
Result result = Result::Ok;
@@ -2109,8 +2124,7 @@ Result BinaryReader::ReadSections() {
ReadEndRestoreGuard guard(this);
read_end_ = state_.offset + section_size;
if (section_code >= kBinarySectionCount) {
- PrintError("invalid section code: %u; max is %u", section_code,
- kBinarySectionCount - 1);
+ PrintError("invalid section code: %u", section_code);
return Result::Error;
}
@@ -2119,10 +2133,11 @@ Result BinaryReader::ReadSections() {
ERROR_UNLESS(read_end_ <= state_.size,
"invalid section size: extends past end");
- ERROR_UNLESS(last_known_section_ == BinarySection::Invalid ||
- section == BinarySection::Custom ||
- section > last_known_section_,
- "section %s out of order", GetSectionName(section));
+ ERROR_UNLESS(
+ last_known_section_ == BinarySection::Invalid ||
+ section == BinarySection::Custom ||
+ GetSectionOrder(section) > GetSectionOrder(last_known_section_),
+ "section %s out of order", GetSectionName(section));
ERROR_UNLESS(!did_read_names_section_ || section == BinarySection::Custom,
"%s section can not occur after Name section",
@@ -2185,6 +2200,12 @@ Result BinaryReader::ReadSections() {
section_result = ReadDataSection(section_size);
result |= section_result;
break;
+ case BinarySection::DataCount:
+ ERROR_UNLESS(options_.features.bulk_memory_enabled(),
+ "invalid section code: %u", section);
+ section_result = ReadDataCountSection(section_size);
+ result |= section_result;
+ break;
case BinarySection::Invalid:
WABT_UNREACHABLE;
}
diff --git a/src/binary-reader.h b/src/binary-reader.h
index 9b100038..9fe0a17a 100644
--- a/src/binary-reader.h
+++ b/src/binary-reader.h
@@ -293,6 +293,11 @@ class BinaryReaderDelegate {
virtual Result EndDataSegment(Index index) = 0;
virtual Result EndDataSection() = 0;
+ /* DataCount section */
+ virtual Result BeginDataCountSection(Offset size) = 0;
+ virtual Result OnDataCount(Index count) = 0;
+ virtual Result EndDataCountSection() = 0;
+
/* Names section */
virtual Result BeginNamesSection(Offset size) = 0;
virtual Result OnModuleNameSubsection(Index index,
diff --git a/src/binary-writer.cc b/src/binary-writer.cc
index b8fa1702..b6c33ccc 100644
--- a/src/binary-writer.cc
+++ b/src/binary-writer.cc
@@ -993,6 +993,12 @@ Result BinaryWriter::WriteModule() {
EndSection();
}
+ if (options_.features.bulk_memory_enabled()) {
+ BeginKnownSection(BinarySection::DataCount);
+ WriteU32Leb128(stream_, module_->data_segments.size(), "data count");
+ EndSection();
+ }
+
if (num_funcs) {
BeginKnownSection(BinarySection::Code);
WriteU32Leb128(stream_, num_funcs, "num functions");
diff --git a/src/binary-writer.h b/src/binary-writer.h
index dc571f46..41e86ff1 100644
--- a/src/binary-writer.h
+++ b/src/binary-writer.h
@@ -18,6 +18,7 @@
#define WABT_BINARY_WRITER_H_
#include "src/common.h"
+#include "src/feature.h"
#include "src/opcode.h"
#include "src/stream.h"
@@ -27,6 +28,17 @@ struct Module;
struct Script;
struct WriteBinaryOptions {
+ WriteBinaryOptions() = default;
+ WriteBinaryOptions(const Features& features,
+ bool canonicalize_lebs,
+ bool relocatable,
+ bool write_debug_names)
+ : features(features),
+ canonicalize_lebs(canonicalize_lebs),
+ relocatable(relocatable),
+ write_debug_names(write_debug_names) {}
+
+ Features features;
bool canonicalize_lebs = true;
bool relocatable = false;
bool write_debug_names = false;
diff --git a/src/binary.cc b/src/binary.cc
index b0cd32a2..6e993ab6 100644
--- a/src/binary.cc
+++ b/src/binary.cc
@@ -18,10 +18,28 @@
namespace wabt {
-const char* g_section_name[] = {
-#define V(NAME, name, code) #NAME,
+BinarySectionOrder GetSectionOrder(BinarySection sec) {
+ switch (sec) {
+#define V(Name, name, code) \
+ case BinarySection::Name: \
+ return BinarySectionOrder::Name;
WABT_FOREACH_BINARY_SECTION(V)
#undef V
-};
+ default:
+ WABT_UNREACHABLE;
+ }
+}
+
+const char* GetSectionName(BinarySection sec) {
+ switch (sec) {
+#define V(Name, name, code) \
+ case BinarySection::Name: \
+ return #Name;
+ WABT_FOREACH_BINARY_SECTION(V)
+#undef V
+ default:
+ WABT_UNREACHABLE;
+ }
+}
} // namespace wabt
diff --git a/src/binary.h b/src/binary.h
index eee09f66..747c28e2 100644
--- a/src/binary.h
+++ b/src/binary.h
@@ -41,6 +41,7 @@
V(Export, export, 7) \
V(Start, start, 8) \
V(Elem, elem, 9) \
+ V(DataCount, data_count, 12) \
V(Code, code, 10) \
V(Data, data, 11)
@@ -51,14 +52,23 @@ enum class BinarySection {
#define V(Name, name, code) Name = code,
WABT_FOREACH_BINARY_SECTION(V)
#undef V
- Invalid,
+ Invalid = ~0,
First = Custom,
- Last = Data,
+ Last = DataCount,
};
/* clang-format on */
static const int kBinarySectionCount = WABT_ENUM_COUNT(BinarySection);
+enum class BinarySectionOrder {
+#define V(Name, name, code) Name,
+ WABT_FOREACH_BINARY_SECTION(V)
+#undef V
+};
+
+BinarySectionOrder GetSectionOrder(BinarySection);
+const char* GetSectionName(BinarySection);
+
enum class NameSectionSubsection {
Module = 0,
Function = 1,
@@ -71,13 +81,6 @@ enum class SegmentFlags : uint8_t {
IndexOther = 2,
};
-extern const char* g_section_name[];
-
-static WABT_INLINE const char* GetSectionName(BinarySection sec) {
- assert(static_cast<int>(sec) < kBinarySectionCount);
- return g_section_name[static_cast<size_t>(sec)];
-}
-
} // namespace wabt
#endif /* WABT_BINARY_H_ */
diff --git a/src/tools/wast2json.cc b/src/tools/wast2json.cc
index 5f5d211f..d48dcb1f 100644
--- a/src/tools/wast2json.cc
+++ b/src/tools/wast2json.cc
@@ -120,6 +120,7 @@ int ProgramMain(int argc, char** argv) {
std::string module_filename_noext =
StripExtension(s_outfile ? s_outfile : s_infile).to_string();
+ s_write_binary_options.features = s_features;
result = WriteBinarySpecScript(
&json_stream, script.get(), s_infile, module_filename_noext,
s_write_binary_options, &module_streams, s_log_stream.get());
diff --git a/src/tools/wat2wasm.cc b/src/tools/wat2wasm.cc
index fe41d49f..c8e04d4d 100644
--- a/src/tools/wat2wasm.cc
+++ b/src/tools/wat2wasm.cc
@@ -148,6 +148,7 @@ int ProgramMain(int argc, char** argv) {
if (Succeeded(result)) {
MemoryStream stream(s_log_stream.get());
+ s_write_binary_options.features = s_features;
result = WriteBinaryModule(&stream, module.get(), s_write_binary_options);
if (Succeeded(result)) {