diff options
author | John Hodge <tpg@ucc.asn.au> | 2017-08-18 13:40:21 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2017-08-18 13:40:21 +0800 |
commit | f55e3c45f16f4d271e528eabbea1bf36f9ffa3c0 (patch) | |
tree | a279d3b6bf384c20940bc773fc36d2d5725d8cb0 | |
parent | 7ee9fc53ab6caa32261496cb76eebda40fbfe000 (diff) | |
download | mrust-f55e3c45f16f4d271e528eabbea1bf36f9ffa3c0.tar.gz |
Trans - VTable unsizing in statics, emit vtables before statics
-rw-r--r-- | src/trans/codegen.cpp | 18 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 14 | ||||
-rw-r--r-- | src/trans/enumerate.cpp | 10 |
3 files changed, 29 insertions, 13 deletions
diff --git a/src/trans/codegen.cpp b/src/trans/codegen.cpp index a571b5e4..e7cea40d 100644 --- a/src/trans/codegen.cpp +++ b/src/trans/codegen.cpp @@ -102,6 +102,15 @@ void Trans_Codegen(const ::std::string& outfile, const TransOptions& opt, const } } } + // VTables (may be needed by statics) + for(const auto& ent : list.m_vtables) + { + const auto& trait = ent.first.m_data.as_UfcsKnown().trait; + const auto& type = *ent.first.m_data.as_UfcsKnown().type; + DEBUG("VTABLE " << trait << " for " << type); + + codegen->emit_vtable(ent.first, crate.get_trait_by_path(Span(), trait.m_path)); + } // 3. Emit statics for(const auto& ent : list.m_statics) { @@ -130,15 +139,6 @@ void Trans_Codegen(const ::std::string& outfile, const TransOptions& opt, const } } - for(const auto& ent : list.m_vtables) - { - const auto& trait = ent.first.m_data.as_UfcsKnown().trait; - const auto& type = *ent.first.m_data.as_UfcsKnown().type; - DEBUG("VTABLE " << trait << " for " << type); - - codegen->emit_vtable(ent.first, crate.get_trait_by_path(Span(), trait.m_path)); - } - // 4. Emit function code for(const auto& ent : list.m_functions) diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 4cd3b7f6..26b0e8a9 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -1535,7 +1535,7 @@ namespace { } else { - if( ty.m_data.is_Borrow() && ty.m_data.as_Borrow().inner->m_data.is_Slice() ) + if( TU_TEST1(ty.m_data, Borrow, .inner->m_data.is_Slice()) ) { // Since this is a borrow, it must be of an array. MIR_ASSERT(*m_mir_res, vi.is_Static(), "BorrowOf returning &[T] not of a static - " << pe.m_path << " is " << vi.tag_str()); @@ -1545,8 +1545,20 @@ namespace { m_of << "{ &" << Trans_Mangle( params.monomorph(m_resolve, e)) << ", " << size << "}"; return ; } + else if( TU_TEST1(ty.m_data, Borrow, .inner->m_data.is_TraitObject()) || TU_TEST1(ty.m_data, Pointer, .inner->m_data.is_TraitObject()) ) + { + const auto& to = (ty.m_data.is_Borrow() ? ty.m_data.as_Borrow().inner : ty.m_data.as_Pointer().inner)->m_data.as_TraitObject(); + const auto& trait_path = to.m_trait.m_path; + MIR_ASSERT(*m_mir_res, vi.is_Static(), "BorrowOf returning &TraitObject not of a static - " << pe.m_path << " is " << vi.tag_str()); + const auto& stat = vi.as_Static(); + auto vtable_path = ::HIR::Path(stat.m_type.clone(), trait_path.clone(), "#vtable"); + m_of << "{ &" << Trans_Mangle( params.monomorph(m_resolve, e)) << ", &" << Trans_Mangle(vtable_path) << "}"; + return ; + } else + { m_of << "&"; + } } ), (UfcsUnknown, diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index b45b72fd..adc9575a 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -51,6 +51,7 @@ void Trans_Enumerate_FillFrom(EnumState& state, const ::HIR::Function& function, void Trans_Enumerate_FillFrom(EnumState& state, const ::HIR::Static& stat, TransList_Static& stat_out, Trans_Params pp={}); void Trans_Enumerate_FillFrom_VTable (EnumState& state, ::HIR::Path vtable_path, const Trans_Params& pp); void Trans_Enumerate_FillFrom_Literal(EnumState& state, const ::HIR::Literal& lit, const Trans_Params& pp); +void Trans_Enumerate_FillFrom_MIR(EnumState& state, const ::MIR::Function& code, const Trans_Params& pp); /// Enumerate trans items starting from `::main` (binary crate) TransList Trans_Enumerate_Main(const ::HIR::Crate& crate) @@ -1181,7 +1182,7 @@ namespace { ), (Static, auto it = impl.m_statics.find(e.item); - if( it == impl.m_statics.end() ) { + if( it == impl.m_statics.end() && e.item != "#vtable" ) { DEBUG("Static " << e.item << " missing in trait " << e.trait << " for " << *e.type); return false; } @@ -1231,14 +1232,17 @@ namespace { TODO(sp, "Associated constant - " << path); ), (Static, + if( e.item == "#vtable" ) + { + DEBUG("VTable, autogen"); + return EntPtr::make_AutoGenerate( {} ); + } auto it = impl.m_statics.find(e.item); if( it != impl.m_statics.end() ) { DEBUG("Found impl" << impl.m_params.fmt_args() << " " << impl.m_type); return EntPtr { &it->second.data }; } - if( e.item == "#vtable" ) - return EntPtr::make_AutoGenerate( {} ); TODO(sp, "Associated static - " << path); ), (Function, |