summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-03-26 18:02:26 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-03-26 18:02:26 +0800
commitdc7f08ff16eb667ef3feb1d6d54573db2c72939a (patch)
tree463220412c10644318a5580ee520c0a7d6f18e42 /src
parenta21f8261532231dd1b0da6788f0ea8fb3e143e00 (diff)
downloadmrust-dc7f08ff16eb667ef3feb1d6d54573db2c72939a.tar.gz
Trans - Handle drop of unsized objects
Diffstat (limited to 'src')
-rw-r--r--src/trans/codegen_c.cpp73
-rw-r--r--src/trans/enumerate.cpp1
2 files changed, 65 insertions, 9 deletions
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index a1440422..e74231e8 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -65,7 +65,7 @@ namespace {
<< "typedef struct { } tTYPEID;\n"
<< "typedef struct { void* PTR; size_t META; } SLICE_PTR;\n"
<< "typedef struct { void* PTR; void* META; } TRAITOBJ_PTR;\n"
- << "typedef struct { size_t size; size_t align; } VTABLE_HDR;\n"
+ << "typedef struct { size_t size; size_t align; void (*drop)(void*); } VTABLE_HDR;\n"
<< "\n"
<< "extern void _Unwind_Resume(void) __attribute__((noreturn));\n"
<< "\n"
@@ -98,6 +98,8 @@ namespace {
<< "\treturn (v&0xFFFFFFFFFFFFFFFF == 0 ? __builtin_ctz64(v>>64) + 64 : __builtin_ctz64(v));\n"
<< "}\n"
<< "\n"
+ << "static inline void noop_drop(void *p) {}\n"
+ << "\n"
;
}
@@ -311,6 +313,21 @@ namespace {
}
m_of << "} "; emit_ctype(ty); m_of << ";\n";
}
+
+ 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, *(::MIR::Function*)nullptr };
+ m_mir_res = &mir_res;
+ m_of << "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);
+ fld_lv.as_Field().field_index ++;
+ }
+ m_of << "}\n";
)
else TU_IFLET( ::HIR::TypeRef::Data, ty.m_data, Function, te,
emit_type_fn(ty);
@@ -407,7 +424,7 @@ namespace {
::std::vector< ::std::pair<::HIR::Pattern,::HIR::TypeRef> > args;
if( item.m_markings.has_drop_impl ) {
- m_of << "tUNIT " << Trans_Mangle( ::HIR::Path(struct_ty.clone(), m_resolve.m_lang_Drop, "drop") ) << "(struct s_" << Trans_Mangle(p) << "*rv);\n";
+ m_of << "tUNIT " << Trans_Mangle( ::HIR::Path(struct_ty.clone(), m_resolve.m_lang_Drop, "drop") ) << "("; emit_ctype(struct_ty_ptr, FMT_CB(ss, ss << "rv";)); m_of << ");\n";
}
else if( m_resolve.is_type_owned_box(struct_ty) )
{
@@ -1179,7 +1196,14 @@ namespace {
m_of << "\t{ ";
m_of << "sizeof("; emit_ctype(type); m_of << "),";
m_of << "__alignof__("; emit_ctype(type); m_of << "),";
- // TODO: Drop glue pointer
+ if( type.m_data.is_Borrow() || m_resolve.type_is_copy(sp, type) )
+ {
+ m_of << "noop_drop,";
+ }
+ else
+ {
+ m_of << "(void*)" << Trans_Mangle(::HIR::Path(type.clone(), "#drop_glue")) << ",";
+ }
m_of << "}"; // No newline, added below
for(unsigned int i = 0; i < trait.m_value_indexes.size(); i ++ )
@@ -2439,7 +2463,17 @@ namespace {
make_fcn = "make_sliceptr"; if(0)
case MetadataType::TraitObject:
make_fcn = "make_traitobjptr";
- m_of << "\t" << Trans_Mangle(p) << "( " << make_fcn << "(&"; emit_lvalue(slot); m_of << ", ";
+ m_of << "\t" << Trans_Mangle(p) << "( " << make_fcn << "(";
+ if( slot.is_Deref() )
+ {
+ emit_lvalue(*slot.as_Deref().val);
+ m_of << ".PTR";
+ }
+ else
+ {
+ m_of << "&"; emit_lvalue(slot);
+ }
+ m_of << ", ";
const auto* lvp = &slot;
while(const auto* le = lvp->opt_Field()) lvp = &*le->val;
MIR_ASSERT(*m_mir_res, lvp->is_Deref(), "Access to unized type without a deref - " << *lvp << " (part of " << slot << ")");
@@ -2474,13 +2508,31 @@ namespace {
),
(TraitObject,
MIR_ASSERT(*m_mir_res, unsized_valid, "Dropping TraitObject without a pointer");
- //MIR_ASSERT(*m_mir_res, slot.is_Deref(), "Dropping a TraitObject through a non-Deref");
// Call destructor in vtable
+ const auto* lvp = &slot;
+ while(const auto* le = lvp->opt_Field()) lvp = &*le->val;
+ MIR_ASSERT(*m_mir_res, lvp->is_Deref(), "Access to unized type without a deref - " << *lvp << " (part of " << slot << ")");
+ m_of << "((VTABLE_HDR*)"; emit_lvalue(*lvp->as_Deref().val); m_of << ".META)->drop(";
+ if( const auto* ve = slot.opt_Deref() )
+ {
+ emit_lvalue(*ve->val); m_of << ".PTR";
+ }
+ else
+ {
+ m_of << "&"; emit_lvalue(slot);
+ }
+ m_of << ");";
),
(Slice,
MIR_ASSERT(*m_mir_res, unsized_valid, "Dropping Slice without a pointer");
- //MIR_ASSERT(*m_mir_res, slot.is_Deref(), "Dropping a slice through a non-Deref");
+ const auto* lvp = &slot;
+ while(const auto* le = lvp->opt_Field()) lvp = &*le->val;
+ MIR_ASSERT(*m_mir_res, lvp->is_Deref(), "Access to unized type without a deref - " << *lvp << " (part of " << slot << ")");
// Call destructor on all entries
+ m_of << "for(unsigned i = 0; i < "; emit_lvalue(*lvp->as_Deref().val); m_of << ".META; i++) {";
+ m_of << "\t\t";
+ emit_destructor_call(::MIR::LValue::make_Index({ box$(slot.clone()), box$(::MIR::LValue::make_Temporary({~0u})) }), *te.inner, false);
+ m_of << "\n\t}";
)
)
}
@@ -2680,7 +2732,10 @@ namespace {
m_of << "var" << e;
),
(Temporary,
- m_of << "tmp" << e.idx;
+ if( e.idx == ~0u )
+ m_of << "i";
+ else
+ m_of << "tmp" << e.idx;
),
(Argument,
m_of << "arg" << e.idx;
@@ -2733,11 +2788,11 @@ namespace {
::HIR::TypeRef tmp;
const auto& ty = m_mir_res->get_lvalue_type(tmp, val);
auto dst_type = metadata_type(ty);
- if( dst_type != MetadataType:: None )
+ if( dst_type != MetadataType::None )
{
m_of << "(*("; emit_ctype(ty); m_of << "*)";
emit_lvalue(*e.val);
- m_of << ")";
+ m_of << ".PTR)";
}
else
{
diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp
index 950d7910..481b275b 100644
--- a/src/trans/enumerate.cpp
+++ b/src/trans/enumerate.cpp
@@ -990,6 +990,7 @@ void Trans_Enumerate_Types(EnumState& state)
tv.m_resolve.expand_associated_types( sp, vtable_params.m_types[idx] );
}
+ tv.visit_type( *ent.first.m_data.as_UfcsKnown().type );
tv.visit_type( ::HIR::TypeRef( ::HIR::GenericPath(vtable_ty_spath, mv$(vtable_params)), &vtable_ref ) );
}