Creating zig1 requires both zig1.c (Over 200 MB) and stage1/wasi.c.
The C compiler then outputs zig1, but this is singlethreaded.
I made zig1-wasm2c output object files using the following patch:
diff --git a/stage1/wasm2c.c b/stage1/wasm2c.c
index 425cc682b8..c6ffe36f47 100644
--- a/stage1/wasm2c.c
+++ b/stage1/wasm2c.c
@@ -76,13 +76,15 @@ static void renderExpr(FILE *out, struct InputStream *in) {
static const uint32_t big_endian = 0xff000000;
int main(int argc, char **argv) {
- if (argc != 3 && argc != 4) {
- fprintf(stderr, "usage: %s <in.wasm.zst> <out.c> [endian]\n", argv[0]);
+ if (argc != 3 && argc != 4 && argc != 5) {
+ fprintf(stderr, "usage: %s <in.wasm.zst> <out.c> [endian] [Output this many C files]\n", argv[0]);
return 1;
}
bool is_big_endian;
+ uint32_t num_c_files = 1;
+
if (argc >= 4) {
if (!strcmp(argv[3], "big")) {
is_big_endian = true;
@@ -96,6 +98,12 @@ int main(int argc, char **argv) {
is_big_endian = *(uint8_t *)&big_endian; // Infer from host endianness.
}
+ if (argc >= 5)
+ num_c_files = strtoul(argv[4], NULL, 0);
+
+ if (num_c_files == ULONG_MAX || num_c_files == 0)
+ panic("strtoul failed");
+
const char *mod = "wasm";
struct InputStream in;
@@ -107,7 +115,14 @@ int main(int argc, char **argv) {
InputStream_readByte(&in) != 'm') panic("input is not a zstd-compressed wasm file");
if (InputStream_readLittle_u32(&in) != 1) panic("unsupported wasm version");
- FILE *out = fopen(argv[2], "wb");
+ FILE *out;
+ if (num_c_files == 1) {
+ out = fopen(argv[2], "wb");
+ } else {
+ out = fopen("zig1.h", "wb");
+ }
+ FILE *tmp_out;
+ FILE **num_c_files_stream;
if (out == NULL) panic("unable to open output file");
fputs("#include <float.h>\n"
"#include <math.h>\n"
@@ -413,7 +428,11 @@ int main(int argc, char **argv) {
for (uint32_t i = 0; i < len; i += 1) {
funcs[i].type_idx = InputStream_readLeb128_u32(&in);
const struct FuncType *func_type = &types[funcs[i].type_idx];
- fputs("static ", out);
+ if (num_c_files == 1) {
+ fputs("static ", out);
+ } else {
+ fputs("extern ", out);
+ }
switch (func_type->result->len) {
case 0: fputs("void", out); break;
case 1: fputs(WasmValType_toC(func_type->result->types[0]), out); break;
@@ -572,12 +591,32 @@ int main(int argc, char **argv) {
uint32_t *param_stash = malloc(sizeof(uint32_t) * max_param_len);
uint32_t len = InputStream_readLeb128_u32(&in);
+ char tmpstrbuffer[64];
+ if (num_c_files > len)
+ num_c_files = len;
+ if (num_c_files > 1){
+ num_c_files_stream = malloc(sizeof(FILE *) * num_c_files);
+ if (num_c_files_stream == NULL)
+ panic("out of memory");
+ for (uint32_t n = 0; n < num_c_files; ++n) {
+ sprintf(tmpstrbuffer, "zig1_%" PRIu32 ".c", n);
+ num_c_files_stream[n] = fopen(tmpstrbuffer, "wb");
+ if (num_c_files_stream[n] == NULL)
+ panic("unable to open file");
+ fputs("#include \"zig1.h\"\n\n", num_c_files_stream[n]);
+ }
+ }
+ tmp_out = out;
for (uint32_t func_i = 0; func_i < len; func_i += 1) {
+ if (num_c_files > 1)
+ out = num_c_files_stream[func_i % num_c_files];
+
FuncGen_reset(&fg);
InputStream_readLeb128_u32(&in);
const struct FuncType *func_type = &types[funcs[func_i].type_idx];
- fputs("static ", out);
+ if (num_c_files == 1)
+ fputs("static ", out);
switch (func_type->result->len) {
case 0: fputs("void", out); break;
case 1: fputs(WasmValType_toC(func_type->result->types[0]), out); break;
@@ -2253,6 +2292,7 @@ int main(int argc, char **argv) {
}
fputs("}\n\n", out);
}
+ out = tmp_out;
}
(void)InputStream_skipToSection(&in, WasmSectionId_data);
This outputs a zig1.h and zig1_N.c files. The zig1_N.c files contains zig1.h and some fN() functions.
Run the command
./zig-wasm2c ../stage1/zig1.wasm zig1.c little <N>
to get <N> c files.
Then get the object files:
find . -type f -name "zig1_*.c" -print0 | xargs -0 -P <N> -I {} gcc {} -c -Os -lm -std=c99 ;
gcc ../stage1/wasi.c -c -Os -lm -std=c99
where <N> is N threads.
When i try to link however:
gcc $(ls zig1_*.o) wasi.o -o zig1_mt.o -Os -lm -std=c99
I get a multiple definition error:
zig1_7.c:(.text+0x26bc9): multiple definition of `load16_align0'; zig1_0.o:zig1_0.c:(.text+0x26b91): first defined here
How do i process from here?