diff options
author | John Hodge <tpg@mutabah.net> | 2017-01-07 12:27:44 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2017-01-07 12:27:44 +0800 |
commit | f4aa141f06676ae6e87b35d635ae848934ad482a (patch) | |
tree | aa41de5ffdee1f3d1a01d494a38db25d0a6ab175 | |
parent | 65e51dc6dc80523c0b2e043c42b6fc14631a043d (diff) | |
download | mrust-f4aa141f06676ae6e87b35d635ae848934ad482a.tar.gz |
Codegen C - Generate code for Fn* vtable for fn types
-rw-r--r-- | src/trans/codegen_c.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 976d5c73..1f54c006 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -828,6 +828,39 @@ namespace { const auto& trait_path = p.m_data.as_UfcsKnown().trait; const auto& type = *p.m_data.as_UfcsKnown().type; + // TODO: Hack in fn pointer VTable handling + if( const auto* te = type.m_data.opt_Function() ) + { + const char* call_fcn_name = nullptr; + if( trait_path.m_path == m_resolve.m_lang_Fn ) + call_fcn_name = "call"; + else if( trait_path.m_path == m_resolve.m_lang_FnMut ) + call_fcn_name = "call_mut"; + else if( trait_path.m_path == m_resolve.m_lang_FnOnce ) + call_fcn_name = "call_once"; + else + ; + + if( call_fcn_name ) + { + auto fcn_p = p.clone(); + fcn_p.m_data.as_UfcsKnown().item = call_fcn_name; + emit_ctype(*te->m_rettype); + auto arg_ty = ::HIR::TypeRef::new_unit(); + for(const auto& ty : te->m_arg_types) + arg_ty.m_data.as_Tuple().push_back( ty.clone() ); + m_of << " " << Trans_Mangle(fcn_p) << "("; emit_ctype(type, FMT_CB(ss, ss << "ptr";)); m_of << ", "; emit_ctype(arg_ty, FMT_CB(ss, ss << "args";)); m_of << ") {\n"; + m_of << "\treturn ptr("; + for(unsigned int i = 0; i < te->m_arg_types.size(); i++) + { + if(i != 0) m_of << ", "; + m_of << "args._" << i; + } + m_of << ");\n"; + m_of << "}\n"; + } + } + { auto vtable_sp = trait_path.m_path; vtable_sp.m_components.back() += "#vtable"; |