pyodide/emsdk/patches/fix_emulate_pointers_dlsym....

100 lines
4.3 KiB
Diff

diff --git a/emsdk/binary/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp
index 9d232c9..60d3990 100644
--- a/emsdk/binaryen/src/passes/FuncCastEmulation.cpp
+++ b/emsdk/binaryen/src/passes/FuncCastEmulation.cpp
@@ -170,23 +170,86 @@ struct FuncCastEmulation : public Pass {
std::stoul(runner->options.getArgumentOrDefault("max-func-params", "16"));
// we just need the one ABI function type for all indirect calls
Signature ABIType(Type(std::vector<Type>(numParams, Type::i64)), Type::i64);
- // Add a thunk for each function in the table, and do the call through it.
+
+ // make sure everything in exports has a thunk
+ // so dlsym works
std::unordered_map<Name, Name> funcThunks;
+ std::unordered_map<Name, Name> exportThunks;
+ for(auto& function: module->exports)
+ {
+ auto& exportName=function->name;
+ auto& exportValue=function->value;
+ // don't create FPCAST emulation for javascript legalizer stubs
+ // (used when javascript doesn't have 64 bit support, so
+ // can't use fpcast emulation calls which need 64 bit support)
+ if(module->getFunctionOrNull(exportValue) && strncmp(exportValue.str,"legalstub$",10)!=0 )
+ {
+ Name exportThunkName = std::string("byn$fpcast-emu$") + exportName.str;
+ auto iter = funcThunks.find(exportValue);
+ if (iter == funcThunks.end())
+ {
+ // an export without a thunk yet - make it and export it
+ auto thunk = makeThunk(exportValue, module, numParams);
+ funcThunks[exportValue] = thunk;
+ exportThunks[exportThunkName]=thunk;
+ }else
+ {
+ // just export existing thunk
+ exportThunks[exportThunkName]=iter->second;
+ }
+ }
+ }
+ int exportCount=0;
+ // Add a thunk for each function in the table, and do the call through it.
for (auto& table : module->tables) {
for (auto& segment : table->segments) {
for (auto& name : segment.data) {
- auto iter = funcThunks.find(name);
- if (iter == funcThunks.end()) {
- auto thunk = makeThunk(name, module, numParams);
- funcThunks[name] = thunk;
- name = thunk;
- } else {
- name = iter->second;
+ // don't create FPCAST emulation for javascript legalizer stubs
+ // (used when javascript doesn't have 64 bit support, so
+ // can't use fpcast emulation calls which need 64 bit support)
+ if(strncmp(name.str,"legalstub$",10)!=0) {
+ auto iter = funcThunks.find(name);
+ if (iter == funcThunks.end()) {
+ // we've already made thunks for exported funcionts so
+ // this is a static function - make the thunk and make an anon export
+ // to it so that it can be called by pyodide
+ Name orig_name(name);
+ auto thunk = makeThunk(name, module, numParams);
+ funcThunks[name] = thunk;
+ exportCount+=1;
+ char buffer[256];
+ snprintf(buffer,256,"byn$fpcast-emu$__static_%d",exportCount);
+ // first make the fpcast version of the function
+ auto* export_ = new Export;
+ export_->name = buffer;
+ export_->value = thunk;
+ export_->kind = ExternalKind::Function;
+ module->addExport(export_);
+ // now make the non-fpcast version
+ snprintf(buffer,256,"__static_%d",exportCount);
+ auto* export2_ = new Export;
+ export2_->name = buffer;
+ export2_->value = orig_name;
+ export2_->kind = ExternalKind::Function;
+ module->addExport(export2_);
+ name = thunk;
+ } else {
+ name = iter->second;
+ }
}
}
}
}
+ // make exports for all export thunks
+ for(auto& thunk: exportThunks) {
+ auto* export_ = new Export;
+ export_->name = thunk.first;
+ export_->value = thunk.second;
+ export_->kind = ExternalKind::Function;
+ module->addExport(export_);
+ }
+
// update call_indirects
ParallelFuncCastEmulation(ABIType, numParams).run(runner, module);
}