mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-23 15:23:44 +02:00
193 lines
6.5 KiB
Diff
193 lines
6.5 KiB
Diff
# Patches wasm2c to distribute the data segments across all the output files when `--num-outputs` is greater than 1 instead of putting them all in a single output file.
|
|
|
|
--- a/include/wabt/c-writer.h
|
|
+++ b/include/wabt/c-writer.h
|
|
@@ -43,6 +43,18 @@ struct WriteCOptions {
|
|
size_t num_imported_functions,
|
|
size_t num_outputs)>
|
|
name_to_output_file_index;
|
|
+ /*
|
|
+ * data_segment_name_to_output_file_index takes const iterators to begin and
|
|
+ * end of a list of all data_segments in the module, and number of .c outputs
|
|
+ * as argument, returns a vector where vector[i] the index of the .c output
|
|
+ * that data_segments_begin + i goes into. Only called when --num-outputs is
|
|
+ * used.
|
|
+ */
|
|
+ std::function<std::vector<size_t>(
|
|
+ std::vector<DataSegment*>::const_iterator data_segments_begin,
|
|
+ std::vector<DataSegment*>::const_iterator data_segments_end,
|
|
+ size_t num_outputs)>
|
|
+ data_segment_name_to_output_file_index;
|
|
};
|
|
|
|
Result WriteC(std::vector<Stream*>&& c_streams,
|
|
--- a/src/c-writer.cc
|
|
+++ b/src/c-writer.cc
|
|
@@ -187,9 +187,10 @@ int GetShiftMask(Type type) {
|
|
* their names, and then divides all non-imported functions into equal-sized
|
|
* buckets (# of non-imported functions / # of .c outputs) based on the sorting.
|
|
*/
|
|
-static std::vector<size_t> default_name_to_output_file_index(
|
|
- std::vector<Func*>::const_iterator func_begin,
|
|
- std::vector<Func*>::const_iterator func_end,
|
|
+template <typename F>
|
|
+std::vector<size_t> default_name_to_output_file_index(
|
|
+ typename std::vector<F*>::const_iterator func_begin,
|
|
+ typename std::vector<F*>::const_iterator func_end,
|
|
size_t num_imports,
|
|
size_t num_streams) {
|
|
std::vector<size_t> result;
|
|
@@ -218,6 +219,14 @@ static std::vector<size_t> default_name_to_output_file_index(
|
|
return result;
|
|
}
|
|
|
|
+static std::vector<size_t> default_data_segment_name_to_output_file_index(
|
|
+ typename std::vector<DataSegment*>::const_iterator data_segment_begin,
|
|
+ typename std::vector<DataSegment*>::const_iterator data_segment_end,
|
|
+ size_t num_streams) {
|
|
+ return default_name_to_output_file_index<DataSegment>(
|
|
+ data_segment_begin, data_segment_end, 0, num_streams);
|
|
+}
|
|
+
|
|
class CWriter {
|
|
public:
|
|
CWriter(std::vector<Stream*>&& c_streams,
|
|
@@ -236,7 +245,15 @@ class CWriter {
|
|
if (c_streams_.size() != 1 && options.name_to_output_file_index) {
|
|
name_to_output_file_index_ = options.name_to_output_file_index;
|
|
} else {
|
|
- name_to_output_file_index_ = default_name_to_output_file_index;
|
|
+ name_to_output_file_index_ = default_name_to_output_file_index<Func>;
|
|
+ }
|
|
+ if (c_streams_.size() != 1 &&
|
|
+ options.data_segment_name_to_output_file_index) {
|
|
+ data_segment_name_to_output_file_index_ =
|
|
+ options.data_segment_name_to_output_file_index;
|
|
+ } else {
|
|
+ data_segment_name_to_output_file_index_ =
|
|
+ default_data_segment_name_to_output_file_index;
|
|
}
|
|
}
|
|
|
|
@@ -407,7 +424,9 @@ class CWriter {
|
|
void WriteElemInstances();
|
|
void WriteGlobalInitializers();
|
|
void WriteDataInitializerDecls();
|
|
+ void WriteDataInitializer(const DataSegment* data_segment);
|
|
void WriteDataInitializers();
|
|
+ void WriteMultiDataInitializers();
|
|
void WriteElemInitializerDecls();
|
|
void WriteElemInitializers();
|
|
void WriteFuncRefWrappers();
|
|
@@ -540,6 +559,11 @@ class CWriter {
|
|
size_t)>
|
|
name_to_output_file_index_;
|
|
|
|
+ std::function<std::vector<size_t>(std::vector<DataSegment*>::const_iterator,
|
|
+ std::vector<DataSegment*>::const_iterator,
|
|
+ size_t)>
|
|
+ data_segment_name_to_output_file_index_;
|
|
+
|
|
bool simd_used_in_header_;
|
|
|
|
bool in_tail_callee_;
|
|
@@ -2218,28 +2242,34 @@ void CWriter::WriteDataInitializerDecls() {
|
|
}
|
|
}
|
|
|
|
+void CWriter::WriteDataInitializer(const DataSegment* data_segment) {
|
|
+ Write(Newline(), InternalSymbolScope(), "const u8 data_segment_data_",
|
|
+ GlobalName(ModuleFieldType::DataSegment, data_segment->name),
|
|
+ "[] = ", OpenBrace());
|
|
+ size_t i = 0;
|
|
+ for (uint8_t x : data_segment->data) {
|
|
+ Writef("0x%02x, ", x);
|
|
+ if ((++i % 12) == 0)
|
|
+ Write(Newline());
|
|
+ }
|
|
+ if (i > 0)
|
|
+ Write(Newline());
|
|
+ Write(CloseBrace(), ";", Newline());
|
|
+}
|
|
+
|
|
void CWriter::WriteDataInitializers() {
|
|
if (module_->memories.empty()) {
|
|
return;
|
|
}
|
|
|
|
- for (const DataSegment* data_segment : module_->data_segments) {
|
|
- if (data_segment->data.empty()) {
|
|
- continue;
|
|
- }
|
|
+ if (c_streams_.size() == 1) {
|
|
+ for (const DataSegment* data_segment : module_->data_segments) {
|
|
+ if (data_segment->data.empty()) {
|
|
+ continue;
|
|
+ }
|
|
|
|
- Write(Newline(), InternalSymbolScope(), "const u8 data_segment_data_",
|
|
- GlobalName(ModuleFieldType::DataSegment, data_segment->name),
|
|
- "[] = ", OpenBrace());
|
|
- size_t i = 0;
|
|
- for (uint8_t x : data_segment->data) {
|
|
- Writef("0x%02x, ", x);
|
|
- if ((++i % 12) == 0)
|
|
- Write(Newline());
|
|
+ WriteDataInitializer(data_segment);
|
|
}
|
|
- if (i > 0)
|
|
- Write(Newline());
|
|
- Write(CloseBrace(), ";", Newline());
|
|
}
|
|
|
|
Write(Newline(), "static void init_memories(", ModuleInstanceTypeName(),
|
|
@@ -2299,6 +2329,36 @@ void CWriter::WriteDataInitializers() {
|
|
}
|
|
}
|
|
|
|
+void CWriter::WriteMultiDataInitializers() {
|
|
+ if (c_streams_.size() == 1 || module_->memories.empty()) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ std::vector<size_t> c_stream_assignment =
|
|
+ data_segment_name_to_output_file_index_(module_->data_segments.begin(),
|
|
+ module_->data_segments.end(),
|
|
+ c_streams_.size());
|
|
+
|
|
+ Index data_segment_index = 0;
|
|
+
|
|
+ for (const DataSegment* data_segment : module_->data_segments) {
|
|
+ if (data_segment->data.empty()) {
|
|
+ ++data_segment_index;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ stream_ = c_streams_.at(c_stream_assignment.at(data_segment_index));
|
|
+
|
|
+ if (stream_->offset() == 0) {
|
|
+ WriteMultiCTop();
|
|
+ }
|
|
+
|
|
+ WriteDataInitializer(data_segment);
|
|
+
|
|
+ ++data_segment_index;
|
|
+ }
|
|
+}
|
|
+
|
|
void CWriter::WriteElemInstances() {
|
|
for (const ElemSegment* elem_segment : module_->elem_segments) {
|
|
std::string name =
|
|
@@ -6099,6 +6159,12 @@ void CWriter::WriteCSource() {
|
|
/* Write function bodies across the different output streams */
|
|
WriteFuncs();
|
|
|
|
+ /*
|
|
+ * Write data segments across the different output streams if there's more
|
|
+ * than one output stream
|
|
+ */
|
|
+ WriteMultiDataInitializers();
|
|
+
|
|
/* For any empty .c output, write a dummy typedef to avoid gcc warning */
|
|
WriteMultiCTopEmpty();
|
|
}
|