diff options
author | John Hodge <tpg@mutabah.net> | 2016-12-04 20:57:37 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-12-04 20:57:37 +0800 |
commit | 44cb8f56e6f2828b588408a9efd1f1fa019ab11c (patch) | |
tree | a72777d75c8af4e013133f02e0da449c5256c89f /src/mir/from_hir.cpp | |
parent | 1cb526a077bfef3aba508927250e3213186cf496 (diff) | |
download | mrust-44cb8f56e6f2828b588408a9efd1f1fa019ab11c.tar.gz |
MIR - Move vtable conversion to its own pass
Diffstat (limited to 'src/mir/from_hir.cpp')
-rw-r--r-- | src/mir/from_hir.cpp | 72 |
1 files changed, 9 insertions, 63 deletions
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 4792d793..cedbb5f5 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -15,6 +15,7 @@ #include <hir_typeck/common.hpp> // monomorphise_type #include "main_bindings.hpp" #include "from_hir.hpp" +#include "operations.hpp" namespace { @@ -1355,7 +1356,6 @@ namespace { void visit(::HIR::ExprNode_CallPath& node) override { - const Span& sp = node.span(); TRACE_FUNCTION_F("_CallPath " << node.m_path); ::std::vector< ::MIR::LValue> values; values.reserve( node.m_args.size() ); @@ -1371,68 +1371,11 @@ namespace { auto next_block = m_builder.new_bb_unlinked(); auto res = m_builder.new_temporary( node.m_res_type ); - // If the call was to a TraitObject function, get it from the vtable. - // TODO: Should this be a later pass? - bool was_virtual = false; - if( node.m_path.m_data.is_UfcsKnown() && node.m_path.m_data.as_UfcsKnown().type->m_data.is_TraitObject() ) - { - const auto& pe = node.m_path.m_data.as_UfcsKnown(); - const auto& te = pe.type->m_data.as_TraitObject(); - if( pe.trait == te.m_trait.m_path ) - { - assert( te.m_trait.m_trait_ptr ); - const auto& trait = *te.m_trait.m_trait_ptr; - - // 1. Get the vtable index for this function - if( trait.m_value_indexes.count(pe.item) == 0 ) - BUG(sp, "Calling method '" << pe.item << "' of " << pe.trait << " which isn't in the vtable"); - unsigned int vtable_idx = trait.m_value_indexes.at( pe.item ); - - // 2. Load from the vtable - auto vtable_rval = ::MIR::RValue::make_DstMeta({ - ::MIR::LValue::make_Deref({ box$(values.front().clone()) }) - }); - auto vtable_ty_spath = pe.trait.m_path; - vtable_ty_spath.m_components.back() += "#vtable"; - const auto& vtable_ref = m_builder.crate().get_struct_by_path(sp, vtable_ty_spath); - // Copy the param set from the trait in the trait object - ::HIR::PathParams vtable_params = te.m_trait.m_path.m_params.clone(); - // - Include associated types on bound - for(const auto& ty_b : te.m_trait.m_type_bounds) { - auto idx = trait.m_type_indexes.at(ty_b.first); - if(vtable_params.m_types.size() <= idx) - vtable_params.m_types.resize(idx+1); - vtable_params.m_types[idx] = ty_b.second.clone(); - } - auto vtable_ty = ::HIR::TypeRef( ::HIR::GenericPath(vtable_ty_spath, mv$(vtable_params)), &vtable_ref ); - - auto vtable = m_builder.lvalue_or_temp(sp, mv$(vtable_ty), mv$(vtable_rval)); - auto vtable_fcn = ::MIR::LValue::make_Field({ box$(vtable), vtable_idx }); - - ::MIR::LValue fcn_val; - m_builder.with_val_type(sp, vtable_fcn, [&](const auto& ty){ - fcn_val = m_builder.new_temporary(ty); - }); - - m_builder.push_stmt_assign( sp, fcn_val.clone(), ::MIR::RValue( mv$(vtable_fcn) ) ); - - was_virtual = true; - m_builder.end_block(::MIR::Terminator::make_CallValue({ - next_block, panic_block, - res.clone(), mv$(fcn_val), - mv$(values) - })); - } - } - - if( ! was_virtual ) - { - m_builder.end_block(::MIR::Terminator::make_CallPath({ - next_block, panic_block, - res.clone(), node.m_path.clone(), - mv$(values) - })); - } + m_builder.end_block(::MIR::Terminator::make_CallPath({ + next_block, panic_block, + res.clone(), node.m_path.clone(), + mv$(values) + })); m_builder.set_cur_block(panic_block); // TODO: Proper panic handling, including scope destruction @@ -1904,6 +1847,9 @@ namespace { root_node.visit( ev ); } + ::HIR::TypeRef ret; + MIR_Cleanup(resolve, ::HIR::ItemPath(), fcn, args, ret); + return ::MIR::FunctionPointer(new ::MIR::Function(mv$(fcn))); } |