diff options
-rw-r--r-- | src/hir/deserialise.cpp | 9 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 9 | ||||
-rw-r--r-- | src/hir_conv/bind.cpp | 8 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 8 | ||||
-rw-r--r-- | src/mir/check.cpp | 11 | ||||
-rw-r--r-- | src/mir/dump.cpp | 8 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 73 | ||||
-rw-r--r-- | src/mir/mir.cpp | 8 | ||||
-rw-r--r-- | src/mir/mir.hpp | 9 | ||||
-rw-r--r-- | src/trans/enumerate.cpp | 8 | ||||
-rw-r--r-- | src/trans/monomorphise.cpp | 13 |
11 files changed, 102 insertions, 62 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index 2d16b230..0b11b4dd 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -952,13 +952,20 @@ namespace { deserialise_mir_lvalue(), deserialise_vec_c<unsigned int>([&](){ return m_in.read_count(); }) }) - _(Call, { + _(CallValue, { static_cast<unsigned int>(m_in.read_count()), static_cast<unsigned int>(m_in.read_count()), deserialise_mir_lvalue(), deserialise_mir_lvalue(), deserialise_vec< ::MIR::LValue>() }) + _(CallPath, { + static_cast<unsigned int>(m_in.read_count()), + static_cast<unsigned int>(m_in.read_count()), + deserialise_mir_lvalue(), + deserialise_path(), + deserialise_vec< ::MIR::LValue>() + }) #undef _ default: throw ""; diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index d890aed6..a1b8924a 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -483,12 +483,19 @@ namespace { for(auto t : e.targets) m_out.write_count(t); ), - (Call, + (CallValue, m_out.write_count(e.ret_block); m_out.write_count(e.panic_block); serialise(e.ret_val); serialise(e.fcn_val); serialise_vec(e.args); + ), + (CallPath, + m_out.write_count(e.ret_block); + m_out.write_count(e.panic_block); + serialise(e.ret_val); + serialise_path(e.fcn_path); + serialise_vec(e.args); ) ) } diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index a83b70d3..911abd1f 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -603,11 +603,17 @@ namespace { (Switch, H::visit_lvalue(*this, te.val); ), - (Call, + (CallValue, H::visit_lvalue(*this, te.ret_val); H::visit_lvalue(*this, te.fcn_val); for(auto& arg : te.args) H::visit_lvalue(*this, arg); + ), + (CallPath, + H::visit_lvalue(*this, te.ret_val); + visit_path(te.fcn_path, ::HIR::Visitor::PathContext::VALUE); + for(auto& arg : te.args) + H::visit_lvalue(*this, arg); ) ) } diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 058d018a..c5aab190 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -1166,13 +1166,9 @@ namespace { (Return, return retval; ), - (Call, + (CallPath, auto& dst = get_lval(e.ret_val); - auto fcn_v = read_lval(e.fcn_val); - if( ! fcn_v.is_BorrowOf() ) { - BUG(sp, "Execute MIR - Calling function through invalid value - " << fcn_v); - } - const auto& fcnp = fcn_v.as_BorrowOf(); + const auto& fcnp = e.fcn_path; auto& fcn = get_function(sp, crate, fcnp); ::std::vector< ::HIR::Literal> call_args; diff --git a/src/mir/check.cpp b/src/mir/check.cpp index 89e75924..aa76139f 100644 --- a/src/mir/check.cpp +++ b/src/mir/check.cpp @@ -350,7 +350,11 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path PUSH_BB(e.targets[i], "Switch V" << i); } ), - (Call, + (CallValue, + PUSH_BB(e.ret_block, "Call ret"); + PUSH_BB(e.panic_block, "Call panic"); + ), + (CallPath, PUSH_BB(e.ret_block, "Call ret"); PUSH_BB(e.panic_block, "Call panic"); ) @@ -566,7 +570,10 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path (Switch, // Check that the condition is an enum ), - (Call, + (CallValue, + // Typecheck arguments and return value + ), + (CallPath, // Typecheck arguments and return value ) ) diff --git a/src/mir/dump.cpp b/src/mir/dump.cpp index da9d0ea9..667d1fd2 100644 --- a/src/mir/dump.cpp +++ b/src/mir/dump.cpp @@ -196,11 +196,17 @@ namespace { m_os << j << " => bb" << e.targets[j] << ", "; m_os << "}\n"; ), - (Call, + (CallValue, m_os << FMT_M(e.ret_val) << " = (" << FMT_M(e.fcn_val) << ")( "; for(const auto& arg : e.args) m_os << FMT_M(arg) << ", "; m_os << ") goto bb" << e.ret_block << " else bb" << e.panic_block << "\n"; + ), + (CallPath, + m_os << FMT_M(e.ret_val) << " = " << e.fcn_path << "( "; + for(const auto& arg : e.args) + m_os << FMT_M(arg) << ", "; + m_os << ") goto bb" << e.ret_block << " else bb" << e.panic_block << "\n"; ) ) dec_indent(); diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 9bc1c287..f4c119bb 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -1239,15 +1239,11 @@ namespace { case ::HIR::ExprNode_Emplace::Type::Noop: throw ""; case ::HIR::ExprNode_Emplace::Type::Boxer: { - auto fcn_ty_data = ::HIR::FunctionType { false, "", box$( place_type.clone() ), {} }; ::HIR::PathParams trait_params; trait_params.m_types.push_back( data_ty.clone() ); - auto fcn_path = ::HIR::Path(place_type.clone(), ::HIR::GenericPath(path_BoxPlace, mv$(trait_params)), "make_place", {}); - auto fcn_val = m_builder.new_temporary( ::HIR::TypeRef(mv$(fcn_ty_data)) ); - m_builder.push_stmt_assign( node.span(), fcn_val.clone(), ::MIR::RValue::make_Constant( ::MIR::Constant(mv$(fcn_path)) ) ); - m_builder.end_block(::MIR::Terminator::make_Call({ + m_builder.end_block(::MIR::Terminator::make_CallPath({ place__ok, place__panic, - place.clone(), mv$(fcn_val), + place.clone(), ::HIR::Path(place_type.clone(), ::HIR::GenericPath(path_BoxPlace, mv$(trait_params)), "make_place", {}), {} })); break; } @@ -1270,14 +1266,11 @@ namespace { { auto place_refmut__type = ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Unique, place_type.clone()); auto place_refmut = m_builder.lvalue_or_temp(node.span(), place_refmut__type, ::MIR::RValue::make_Borrow({ 0, ::HIR::BorrowType::Unique, place.clone() })); - auto fcn_ty_data = ::HIR::FunctionType { false, "", box$( place_raw__type.clone() ), ::make_vec1(mv$(place_refmut__type)) }; // <typeof(place) as ops::Place<T>>::pointer (T = inner) auto fcn_path = ::HIR::Path(place_type.clone(), ::HIR::GenericPath(path_Place, ::HIR::PathParams(data_ty.clone())), "pointer"); - auto fcn_val = m_builder.new_temporary( ::HIR::TypeRef(mv$(fcn_ty_data)) ); - m_builder.push_stmt_assign( node.span(), fcn_val.clone(), ::MIR::RValue::make_Constant( ::MIR::Constant(mv$(fcn_path)) ) ); - m_builder.end_block(::MIR::Terminator::make_Call({ + m_builder.end_block(::MIR::Terminator::make_CallPath({ place_raw__ok, place_raw__panic, - place_raw.clone(), mv$(fcn_val), + place_raw.clone(), mv$(fcn_path), ::make_vec1( mv$(place_refmut) ) })); } @@ -1311,16 +1304,11 @@ namespace { auto res = m_builder.new_temporary( node.m_res_type ); auto res__panic = m_builder.new_bb_unlinked(); auto res__ok = m_builder.new_bb_unlinked(); - { - auto fcn_ty_data = ::HIR::FunctionType { true, "", box$(node.m_res_type.clone()), ::make_vec1(mv$(place_type)) }; - auto fcn_val = m_builder.new_temporary( ::HIR::TypeRef(mv$(fcn_ty_data)) ); - m_builder.push_stmt_assign( node.span(), fcn_val.clone(), ::MIR::RValue::make_Constant( ::MIR::Constant(mv$(finalize_path)) ) ); - m_builder.end_block(::MIR::Terminator::make_Call({ - res__ok, res__panic, - res.clone(), mv$(fcn_val), - ::make_vec1( mv$(place) ) - })); - } + m_builder.end_block(::MIR::Terminator::make_CallPath({ + res__ok, res__panic, + res.clone(), mv$(finalize_path), + ::make_vec1( mv$(place) ) + })); // TODO: Proper panic handling, including scope destruction m_builder.set_cur_block(res__panic); @@ -1362,9 +1350,13 @@ namespace { m_builder.moved_lvalue( arg->span(), values.back() ); } - ::MIR::LValue fcn_val; + + auto panic_block = m_builder.new_bb_unlinked(); + 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() ) { @@ -1400,41 +1392,32 @@ namespace { 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 ) { - // TODO: Obtain function type for this function (i.e. a type that is specifically for this function) - auto fcn_ty_data = ::HIR::FunctionType { - false, - "", - box$( node.m_cache.m_arg_types.back().clone() ), - {} - }; - for(unsigned int i = 0; i < node.m_cache.m_arg_types.size() - 1; i ++) - { - fcn_ty_data.m_arg_types.push_back( node.m_cache.m_arg_types[i].clone() ); - } - fcn_val = m_builder.new_temporary( ::HIR::TypeRef(mv$(fcn_ty_data)) ); - m_builder.push_stmt_assign( sp, fcn_val.clone(), ::MIR::RValue::make_Constant( ::MIR::Constant(node.m_path.clone()) ) ); + m_builder.end_block(::MIR::Terminator::make_CallPath({ + next_block, panic_block, + res.clone(), node.m_path.clone(), + mv$(values) + })); } - auto panic_block = m_builder.new_bb_unlinked(); - auto next_block = m_builder.new_bb_unlinked(); - auto res = m_builder.new_temporary( node.m_res_type ); - m_builder.end_block(::MIR::Terminator::make_Call({ - next_block, panic_block, - res.clone(), mv$(fcn_val), - mv$(values) - })); - m_builder.set_cur_block(panic_block); // TODO: Proper panic handling, including scope destruction m_builder.end_block( ::MIR::Terminator::make_Diverge({}) ); @@ -1465,7 +1448,7 @@ namespace { auto panic_block = m_builder.new_bb_unlinked(); auto next_block = m_builder.new_bb_unlinked(); auto res = m_builder.new_temporary( node.m_res_type ); - m_builder.end_block(::MIR::Terminator::make_Call({ + m_builder.end_block(::MIR::Terminator::make_CallValue({ next_block, panic_block, res.clone(), mv$(fcn_val), mv$(values) diff --git a/src/mir/mir.cpp b/src/mir/mir.cpp index 18c69a41..5b3a705d 100644 --- a/src/mir/mir.cpp +++ b/src/mir/mir.cpp @@ -154,11 +154,17 @@ namespace MIR { os << j << " => bb" << e.targets[j] << ", "; os << ")"; ), - (Call, + (CallValue, os << "Call( " << e.ret_val << " = " << e.fcn_val << "( "; for(const auto& arg : e.args) os << arg << ", "; os << "), bb" << e.ret_block << ", bb" << e.panic_block << ")"; + ), + (CallPath, + os << "Call( " << e.ret_val << " = " << e.fcn_path << "( "; + for(const auto& arg : e.args) + os << arg << ", "; + os << "), bb" << e.ret_block << ", bb" << e.panic_block << ")"; ) ) diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp index bf5e2d4a..c01dcbd7 100644 --- a/src/mir/mir.hpp +++ b/src/mir/mir.hpp @@ -175,12 +175,19 @@ TAGGED_UNION(Terminator, Incomplete, LValue val; ::std::vector<BasicBlockId> targets; }), - (Call, struct { + (CallValue, struct { BasicBlockId ret_block; BasicBlockId panic_block; LValue ret_val; LValue fcn_val; ::std::vector<LValue> args; + }), + (CallPath, struct { + BasicBlockId ret_block; + BasicBlockId panic_block; + LValue ret_val; + ::HIR::Path fcn_path; + ::std::vector<LValue> args; }) ); extern ::std::ostream& operator<<(::std::ostream& os, const Terminator& x); diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index 2c918a89..f8e64396 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -455,11 +455,17 @@ void Trans_Enumerate_FillFrom_MIR(TransList& out, const ::HIR::Crate& crate, con (Switch, Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.val, pp); ), - (Call, + (CallValue, Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.ret_val, pp); Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.fcn_val, pp); for(const auto& arg : e.args) Trans_Enumerate_FillFrom_MIR_LValue(out,crate, arg, pp); + ), + (CallPath, + Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.ret_val, pp); + Trans_Enumerate_FillFrom_Path(out,crate, e.fcn_path, pp); + for(const auto& arg : e.args) + Trans_Enumerate_FillFrom_MIR_LValue(out,crate, arg, pp); ) ) } diff --git a/src/trans/monomorphise.cpp b/src/trans/monomorphise.cpp index e6ae2885..9d2f1b1c 100644 --- a/src/trans/monomorphise.cpp +++ b/src/trans/monomorphise.cpp @@ -247,13 +247,22 @@ namespace { e.targets }); ), - (Call, - terminator = ::MIR::Terminator::make_Call({ + (CallValue, + terminator = ::MIR::Terminator::make_CallValue({ e.ret_block, e.panic_block, monomorph_LValue(crate, params, e.ret_val), monomorph_LValue(crate, params, e.fcn_val), monomorph_LValue_list(crate, params, e.args) }); + ), + (CallPath, + // TODO: Replace vtable calls + terminator = ::MIR::Terminator::make_CallPath({ + e.ret_block, e.panic_block, + monomorph_LValue(crate, params, e.ret_val), + params.monomorph(crate, e.fcn_path), + monomorph_LValue_list(crate, params, e.args) + }); ) ) |