mirror of https://github.com/pyodide/pyodide.git
100 lines
4.3 KiB
Diff
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);
|
|
}
|