mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-24 15:53:45 +02:00

This prevents the TOC (table of contents) on PowerPC targets from being overflowed by the sizes of the files generated by wasm2c. It should also help improve compilation times. I'll be submitting this patch as a pull request to WABT later.
191 lines
6.6 KiB
Diff
191 lines
6.6 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,15 @@ 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 +246,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 +425,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 +560,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 +2243,35 @@ 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 +2331,32 @@ 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));
|
|
+
|
|
+ WriteDataInitializer(data_segment);
|
|
+
|
|
+ ++data_segment_index;
|
|
+ }
|
|
+}
|
|
+
|
|
void CWriter::WriteElemInstances() {
|
|
for (const ElemSegment* elem_segment : module_->elem_segments) {
|
|
std::string name =
|
|
@@ -6099,6 +6157,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();
|
|
}
|