diff options
author | John Hodge <tpg@mutabah.net> | 2018-03-07 22:07:38 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2018-03-17 18:52:16 +0800 |
commit | 912f54efc564f1928b70349960e0eee6020242fe (patch) | |
tree | 0cac524044d9c2d6ccde629a9585fd60e39446ef /src | |
parent | 5118328a10bf3042f4301080cb72762ed4c0ca49 (diff) | |
download | mrust-912f54efc564f1928b70349960e0eee6020242fe.tar.gz |
VTables - Rename vtable static to have the # at the end (helps parsing in mmir)
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_expand/vtable.cpp | 6 | ||||
-rw-r--r-- | src/mir/cleanup.cpp | 4 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 2 | ||||
-rw-r--r-- | src/trans/codegen_mmir.cpp | 162 | ||||
-rw-r--r-- | src/trans/enumerate.cpp | 8 | ||||
-rw-r--r-- | src/trans/mangling.cpp | 13 |
6 files changed, 147 insertions, 48 deletions
diff --git a/src/hir_expand/vtable.cpp b/src/hir_expand/vtable.cpp index 81c0de00..4bc1cbc5 100644 --- a/src/hir_expand/vtable.cpp +++ b/src/hir_expand/vtable.cpp @@ -165,7 +165,7 @@ namespace { ) ); ), (Static, - if( vi.first != "#vtable" ) + if( vi.first != "vtable#" ) { TODO(Span(), "Associated static in vtable"); } @@ -229,7 +229,7 @@ namespace { ::HIR::GenericPath path( mv$(item_path), mv$(params) ); tr.m_values.insert( ::std::make_pair( - "#vtable", + "vtable#", ::HIR::TraitValueItem(::HIR::Static { ::HIR::Linkage(), false, ::HIR::TypeRef( mv$(path) ), {},{} }) ) ); } @@ -269,7 +269,7 @@ namespace { } const auto& vtable_ref = m_crate.get_struct_by_path(sp, vtable_sp); - impl.m_statics.insert(::std::make_pair( "#vtable", ::HIR::TraitImpl::ImplEnt<::HIR::Static> { true, ::HIR::Static { + impl.m_statics.insert(::std::make_pair( "vtable#", ::HIR::TraitImpl::ImplEnt<::HIR::Static> { true, ::HIR::Static { ::HIR::Linkage(), false, ::HIR::TypeRef::new_path(::HIR::GenericPath(mv$(vtable_sp), mv$(vtable_params)), &vtable_ref), diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp index fef5d350..019a0796 100644 --- a/src/mir/cleanup.cpp +++ b/src/mir/cleanup.cpp @@ -376,7 +376,7 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR ::HIR::TypeRef tmp; const auto& ty = state.get_static_type(tmp, path); - auto vtable_path = ::HIR::Path(&ty == &tmp ? mv$(tmp) : ty.clone(), tep->m_trait.m_path.clone(), "#vtable"); + auto vtable_path = ::HIR::Path(&ty == &tmp ? mv$(tmp) : ty.clone(), tep->m_trait.m_path.clone(), "vtable#"); auto vtable_val = ::MIR::Param( ::MIR::Constant::make_ItemAddr(mv$(vtable_path)) ); @@ -678,7 +678,7 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator& { MIR_ASSERT(state, state.m_resolve.type_is_sized(state.sp, src_ty), "Attempting to get vtable for unsized type - " << src_ty); - ::HIR::Path vtable { src_ty.clone(), trait_path.m_path.clone(), "#vtable" }; + ::HIR::Path vtable { src_ty.clone(), trait_path.m_path.clone(), "vtable#" }; out_meta_val = ::MIR::Constant::make_ItemAddr(mv$(vtable)); } } diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index c7750209..976b94fa 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -1651,7 +1651,7 @@ namespace { 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"); + 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 ; } diff --git a/src/trans/codegen_mmir.cpp b/src/trans/codegen_mmir.cpp index cea409bf..22c232b2 100644 --- a/src/trans/codegen_mmir.cpp +++ b/src/trans/codegen_mmir.cpp @@ -197,30 +197,42 @@ namespace const auto* repr = Target_GetTypeRepr(sp, m_resolve, ty); MIR_ASSERT(*m_mir_res, repr, "No repr for tuple " << ty); + bool has_drop_glue = m_resolve.type_needs_drop_glue(sp, ty); + auto drop_glue_path = ::HIR::Path(ty.clone(), "drop_glue#"); + m_of << "type " << ty << " {\n"; m_of << "\tSIZE " << repr->size << ", ALIGN " << repr->align << ";\n"; + if( has_drop_glue ) + { + m_of << "\tDROP " << drop_glue_path << ";\n"; + } for(const auto& e : repr->fields) { m_of << "\t" << e.offset << " = " << e.ty << ";\n"; } m_of << "}\n"; + + if( has_drop_glue ) + { + m_of << "fn " << drop_glue_path << "(&move " << ty << ") {\n"; + m_of << "\tlet unit: ();\n"; + + m_of << "\t0: {\n"; + + auto self = ::MIR::LValue::make_Deref({ box$(::MIR::LValue::make_Argument({0})) }); + auto fld_lv = ::MIR::LValue::make_Field({ box$(self), 0 }); + for(const auto& e : repr->fields) + { + if( !m_resolve.type_is_copy(sp, e.ty) ) { + m_of << "\t\t""DROP " << fmt(fld_lv) << ";\n"; + } + fld_lv.as_Field().field_index += 1; + } + m_of << "\t\t""RETURN\n"; + m_of << "\t}\n"; + m_of << "}\n"; + } } -#if 0 - auto drop_glue_path = ::HIR::Path(ty.clone(), "#drop_glue"); - auto args = ::std::vector< ::std::pair<::HIR::Pattern,::HIR::TypeRef> >(); - auto ty_ptr = ::HIR::TypeRef::new_pointer(::HIR::BorrowType::Owned, ty.clone()); - ::MIR::TypeResolve mir_res { sp, m_resolve, FMT_CB(ss, ss << drop_glue_path;), ty_ptr, args, empty_fcn }; - m_mir_res = &mir_res; - m_of << "static void " << Trans_Mangle(drop_glue_path) << "("; emit_ctype(ty); m_of << "* rv) {"; - auto self = ::MIR::LValue::make_Deref({ box$(::MIR::LValue::make_Return({})) }); - auto fld_lv = ::MIR::LValue::make_Field({ box$(self), 0 }); - for(const auto& ity : te) - { - emit_destructor_call(fld_lv, ity, /*unsized_valid=*/false, 1); - fld_lv.as_Field().field_index ++; - } - m_of << "}\n"; -#endif } else { } @@ -228,6 +240,61 @@ namespace m_mir_res = nullptr; } + // TODO: Move this to a more common location + MetadataType metadata_type(const ::HIR::TypeRef& ty) const + { + if( ty == ::HIR::CoreType::Str || ty.m_data.is_Slice() ) { + return MetadataType::Slice; + } + else if( ty.m_data.is_TraitObject() ) { + return MetadataType::TraitObject; + } + else if( ty.m_data.is_Path() ) + { + const auto& te = ty.m_data.as_Path(); + switch( te.binding.tag() ) + { + TU_ARM(te.binding, Struct, tpb) { + switch( tpb->m_struct_markings.dst_type ) + { + case ::HIR::StructMarkings::DstType::None: + return MetadataType::None; + case ::HIR::StructMarkings::DstType::Possible: { + // TODO: How to figure out? Lazy way is to check the monomorpised type of the last field (structs only) + const auto& path = ty.m_data.as_Path().path.m_data.as_Generic(); + const auto& str = *ty.m_data.as_Path().binding.as_Struct(); + auto monomorph = [&](const auto& tpl) { + auto rv = monomorphise_type(sp, str.m_params, path.m_params, tpl); + m_resolve.expand_associated_types(sp, rv); + return rv; + }; + TU_MATCHA( (str.m_data), (se), + (Unit, MIR_BUG(*m_mir_res, "Unit-like struct with DstType::Possible"); ), + (Tuple, return metadata_type( monomorph(se.back().ent) ); ), + (Named, return metadata_type( monomorph(se.back().second.ent) ); ) + ) + //MIR_TODO(*m_mir_res, "Determine DST type when ::Possible - " << ty); + return MetadataType::None; + } + case ::HIR::StructMarkings::DstType::Slice: + return MetadataType::Slice; + case ::HIR::StructMarkings::DstType::TraitObject: + return MetadataType::TraitObject; + } + } break; + TU_ARM(te.binding, Union, tpb) + return MetadataType::None; + TU_ARM(te.binding, Enum, tpb) + return MetadataType::None; + default: + MIR_BUG(*m_mir_res, "Unbound/opaque path in trans - " << ty); + } + } + else { + return MetadataType::None; + } + } + void emit_struct(const Span& sp, const ::HIR::GenericPath& p, const ::HIR::Struct& item) override { ::MIR::Function empty_fcn; @@ -236,20 +303,51 @@ namespace auto drop_glue_path = ::HIR::Path(::HIR::TypeRef(p.clone(), &item), "drop_glue#"); - bool is_vtable; { - const auto& lc = p.m_path.m_components.back(); - is_vtable = (lc.size() > 7 && ::std::strcmp(lc.c_str() + lc.size() - 7, "#vtable") == 0); - }; - TRACE_FUNCTION_F(p); ::HIR::TypeRef ty = ::HIR::TypeRef::new_path(p.clone(), &item); - // HACK: For vtables, insert the alignment and size at the start - // TODO: Add this to the vtable in the HIR instead - if(is_vtable) - { - //m_of << "\tVTABLE_HDR hdr;\n"; - } + struct H { + static ::HIR::TypeRef get_metadata_type(const Span& sp, const ::StaticTraitResolve& resolve, const TypeRepr& r) + { + ASSERT_BUG(sp, r.fields.size() > 0, ""); + auto& t = r.fields.back().ty; + if( t == ::HIR::CoreType::Str ) { + return ::HIR::CoreType::Usize; + } + else if( t.m_data.is_Slice() ) { + return ::HIR::CoreType::Usize; + } + else if( t.m_data.is_TraitObject() ) { + const auto& te = t.m_data.as_TraitObject(); + //auto vtp = t.m_data.as_TraitObject().m_trait.m_path; + + auto vtable_gp = te.m_trait.m_path.clone(); + vtable_gp.m_path.m_components.back() += "#vtable"; + const auto& trait = resolve.m_crate.get_trait_by_path(sp, te.m_trait.m_path.m_path); + vtable_gp.m_params.m_types.resize( vtable_gp.m_params.m_types.size() + trait.m_type_indexes.size() ); + for(const auto& ty : trait.m_type_indexes) { + auto aty = te.m_trait.m_type_bounds.at(ty.first).clone(); + vtable_gp.m_params.m_types.at(ty.second) = ::std::move(aty); + } + for(auto& e : vtable_gp.m_params.m_types) + { + ASSERT_BUG(sp, e != ::HIR::TypeRef(), ""); + } + + const auto& vtable_ref = resolve.m_crate.get_struct_by_path(sp, vtable_gp.m_path); + return ::HIR::TypeRef::new_pointer(::HIR::BorrowType::Shared, ::HIR::TypeRef::new_path( ::std::move(vtable_gp), &vtable_ref )); + } + else if( t.m_data.is_Path() ) { + auto* repr = Target_GetTypeRepr(sp, resolve, t); + ASSERT_BUG(sp, repr, "No repr for " << t); + return get_metadata_type(sp, resolve, *repr); + } + else { + BUG(sp, "Unexpected type in get_metadata_type - " << t); + } + } + }; + // TODO: Generate the drop glue (and determine if there is any) bool has_drop_glue = m_resolve.type_needs_drop_glue(sp, ty); @@ -258,6 +356,10 @@ namespace MIR_ASSERT(*m_mir_res, repr, "No repr for struct " << ty); m_of << "type " << p << " {\n"; m_of << "\tSIZE " << repr->size << ", ALIGN " << repr->align << ";\n"; + if( repr->size == SIZE_MAX ) + { + m_of << "\tDSTMETA " << H::get_metadata_type(sp, m_resolve, *repr) << ";\n"; + } if( has_drop_glue ) { m_of << "\tDROP " << drop_glue_path << ";\n"; @@ -319,10 +421,10 @@ namespace auto fld_lv = ::MIR::LValue::make_Field({ box$(self), 0 }); for(const auto& e : repr->fields) { - fld_lv.as_Field().field_index += 1; if( !m_resolve.type_is_copy(sp, e.ty) ) { m_of << "\t\t""DROP " << fmt(fld_lv) << ";\n"; } + fld_lv.as_Field().field_index += 1; } } m_of << "\t\t""RETURN\n"; @@ -432,7 +534,7 @@ namespace m_of << "\\0"; } m_of << "\";\n"; - m_of << "\t#" << int(1 - e.zero_variant) << ";\n"; + m_of << "\t#" << int(1 - e.zero_variant) << " =" << int(1 - e.zero_variant) << ";\n"; } break; } m_of << "}\n"; @@ -913,7 +1015,7 @@ namespace m_of << "DSTPTR " << fmt(e.val); break; TU_ARM(se.src, MakeDst, e) - m_of << "MAKEDST " << fmt(e.ptr_val) << ", " << fmt(e.ptr_val); + m_of << "MAKEDST " << fmt(e.ptr_val) << ", " << fmt(e.meta_val); break; TU_ARM(se.src, Variant, e) m_of << "VARIANT " << e.path << " " << e.index << " " << fmt(e.val); diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index cecf87de..fbf747f8 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -191,7 +191,7 @@ TransList Trans_Enumerate_Public(::HIR::Crate& crate) else if( vi.second.is_Function() && vi.second.as_Function().m_params.m_types.size() > 0 ) ; // VTable, magic - else if( vi.first == "#vtable" ) + else if( vi.first == "vtable#" ) ; else { @@ -1226,7 +1226,7 @@ namespace { is_spec = it->second.is_specialisable; ), (Static, - if( pe->item == "#vtable" ) { + if( pe->item == "vtable#" ) { is_spec = true; break; } @@ -1281,7 +1281,7 @@ namespace { TODO(sp, "Associated constant - " << path); ), (Static, - if( pe->item == "#vtable" ) + if( pe->item == "vtable#" ) { DEBUG("VTable, autogen"); return EntPtr::make_AutoGenerate( {} ); @@ -1357,7 +1357,7 @@ void Trans_Enumerate_FillFrom_Path(EnumState& state, const ::HIR::Path& path, co state.rv.m_constructors.insert( mv$(path_mono.m_data.as_Generic()) ); } // - <T as U>::#vtable - else if( path_mono.m_data.is_UfcsKnown() && path_mono.m_data.as_UfcsKnown().item == "#vtable" ) + else if( path_mono.m_data.is_UfcsKnown() && path_mono.m_data.as_UfcsKnown().item == "vtable#" ) { if( state.rv.add_vtable( path_mono.clone(), {} ) ) { diff --git a/src/trans/mangling.cpp b/src/trans/mangling.cpp index 78409827..741d13dd 100644 --- a/src/trans/mangling.cpp +++ b/src/trans/mangling.cpp @@ -13,6 +13,7 @@ * $P = + symbol * $E = = symbol * $C = , symbol + * $H = # symbol * $pL/$pR = Left/right paren * $aL/$aR = Left/right angle (<>) */ @@ -104,10 +105,8 @@ namespace { ss << "_as_"; ss << Trans_Mangle(pe.trait); ss << "$aR"; - if( pe.item[0] == '#' ) - ss << (pe.item.size()-1+2) << "$H" << (pe.item.c_str()+1); - else - ss << pe.item; + auto v = escape_str(pe.item); + ss << v.size() << v; ss << emit_params(pe.params); ); ), @@ -116,10 +115,8 @@ namespace { ss << "_ZRI$aL"; ss << Trans_Mangle(*pe.type); ss << "$aR"; - if( pe.item[0] == '#' ) - ss << (pe.item.size()-1+2) << "$H" << (pe.item.c_str()+1); - else - ss << pe.item; + auto v = escape_str(pe.item); + ss << v.size() << v; ss << emit_params(pe.params); ); ) |