@@ -50,6 +50,13 @@ struct LLVMOpt : public Pass {
50
50
for (auto & e : module ->exports ) {
51
51
originalExports.insert (e->name );
52
52
}
53
+ // We will add additional exports, some of which we can forget about
54
+ // imediately, but others we need to keep around until almost the very end
55
+ // because we need to use them.
56
+ // For example, we add an export for the start function if there is one, and
57
+ // we find it in the output wasm and use it to find the start function. We
58
+ // can then remove the export
59
+ std::set<Name> usedExports;
53
60
54
61
// Add exports for more things that we need, either for the wasm2c runtime,
55
62
// or to make it easy for us to find what we need afterwards. (We will
@@ -65,10 +72,18 @@ struct LLVMOpt : public Pass {
65
72
}
66
73
// Ensure a _start is exported, which wasm2c expects.
67
74
if (!module ->getExportOrNull (" _start" )) {
75
+ Name name (" byn_llvm_runtime_start" );
68
76
module ->addFunction (builder.makeFunction (
69
- " byn$llvm-start " , {Type::none, Type::none}, {}, builder.makeNop ()));
77
+ name , {Type::none, Type::none}, {}, builder.makeNop ()));
70
78
module ->addExport (
71
- builder.makeExport (" _start" , " byn$llvm-start" , ExternalKind::Function));
79
+ builder.makeExport (" _start" , name, ExternalKind::Function));
80
+ }
81
+ // Export the wasm start function, if there is one.
82
+ Name wasmStartExport (" byn_llvm_wasm_start" );
83
+ if (module ->start .is ()) {
84
+ module ->addExport (
85
+ builder.makeExport (wasmStartExport, module ->start , ExternalKind::Function));
86
+ usedExports.insert (wasmStartExport);
72
87
}
73
88
74
89
// Write the module to a temp file.
@@ -103,14 +118,18 @@ struct LLVMOpt : public Pass {
103
118
std::string cmd =
104
119
" emcc " + tempC + " -o " + tempWasmC + " -O1 -s EXPORTED_FUNCTIONS=" ;
105
120
bool first = true ;
106
- for (auto e : originalExports) {
107
- if (first) {
108
- first = false ;
109
- } else {
110
- cmd += ' ,' ;
121
+ auto addExports = [&](const std::set<Name>& names) {
122
+ for (auto e : names) {
123
+ if (first) {
124
+ first = false ;
125
+ } else {
126
+ cmd += ' ,' ;
127
+ }
128
+ cmd += std::string (" _w2c_" ) + e.str ;
111
129
}
112
- cmd += std::string (" _w2c_" ) + e.str ;
113
- }
130
+ };
131
+ addExports (originalExports);
132
+ addExports (usedExports);
114
133
ProgramResult c2wasm (cmd);
115
134
if (c2wasm.failed ()) {
116
135
c2wasm.dump (std::cout);
@@ -135,6 +154,11 @@ struct LLVMOpt : public Pass {
135
154
return false ;
136
155
}),
137
156
module ->exports .end ());
157
+ module ->updateMaps ();
158
+ // Find the important things we exported so that we could find them later.
159
+ if (auto * e = module ->getExportOrNull (wasmStartExport)) {
160
+ module ->start = e->value ;
161
+ }
138
162
// Remove the table: the "native" table contains things the new sandboxing
139
163
// layer in C added and needs. We want to look into the wasm in that
140
164
// sandbox.
0 commit comments