summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/trans/codegen_mmir.cpp151
-rw-r--r--tools/standalone_miri/hir_sim.hpp3
-rw-r--r--tools/standalone_miri/main.cpp66
-rw-r--r--tools/standalone_miri/module_tree.cpp19
-rw-r--r--tools/standalone_miri/module_tree.hpp6
5 files changed, 145 insertions, 100 deletions
diff --git a/src/trans/codegen_mmir.cpp b/src/trans/codegen_mmir.cpp
index 703ef44d..88c81568 100644
--- a/src/trans/codegen_mmir.cpp
+++ b/src/trans/codegen_mmir.cpp
@@ -182,39 +182,6 @@ namespace
m_of.close();
}
- /*
- void emit_box_drop_glue(::HIR::GenericPath p, const ::HIR::Struct& item)
- {
- auto struct_ty = ::HIR::TypeRef( p.clone(), &item );
- auto drop_glue_path = ::HIR::Path(struct_ty.clone(), "#drop_glue");
- auto struct_ty_ptr = ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Owned, struct_ty.clone());
- // - Drop Glue
- const auto* ity = m_resolve.is_type_owned_box(struct_ty);
-
- auto inner_ptr = ::HIR::TypeRef::new_pointer( ::HIR::BorrowType::Unique, ity->clone() );
- auto box_free = ::HIR::GenericPath { m_crate.get_lang_item_path(sp, "box_free"), { ity->clone() } };
-
- ::std::vector< ::std::pair<::HIR::Pattern,::HIR::TypeRef> > args;
- args.push_back( ::std::make_pair( ::HIR::Pattern {}, mv$(inner_ptr) ) );
-
- ::MIR::Function empty_fcn;
- ::MIR::TypeResolve mir_res { sp, m_resolve, FMT_CB(ss, ss << drop_glue_path;), struct_ty_ptr, args, empty_fcn };
- m_mir_res = &mir_res;
- m_of << "fn " << Trans_Mangle(drop_glue_path) << "(" << Trans_Mangle(p) << ") {\n";
-
- // Obtain inner pointer
- // TODO: This is very specific to the structure of the official liballoc's Box.
- m_of << "\tlet arg1: "; emit_type(args[0].second); m_of << "\n";
- // Call destructor of inner data
- emit_destructor_call( ::MIR::LValue::make_Deref({ box$(::MIR::LValue::make_Argument({0})) }), *ity, true, 1);
- // Emit a call to box_free for the type
- m_of << "\t" << Trans_Mangle(box_free) << "(arg0);\n";
-
- m_of << "}\n";
- m_mir_res = nullptr;
- }
- */
-
void emit_type(const ::HIR::TypeRef& ty) override
{
@@ -267,6 +234,8 @@ namespace
::MIR::TypeResolve top_mir_res { sp, m_resolve, FMT_CB(ss, ss << "struct " << p;), ::HIR::TypeRef(), {}, empty_fcn };
m_mir_res = &top_mir_res;
+ 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);
@@ -282,79 +251,84 @@ namespace
//m_of << "\tVTABLE_HDR hdr;\n";
}
+ // TODO: Generate the drop glue (and determine if there is any)
+ bool has_drop_glue = m_resolve.type_needs_drop_glue(sp, ty);
+
const auto* repr = Target_GetTypeRepr(sp, m_resolve, ty);
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( 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";
- // TODO: Drop glue!
-#if 0
- auto struct_ty = ::HIR::TypeRef(p.clone(), &item);
- auto drop_glue_path = ::HIR::Path(struct_ty.clone(), "#drop_glue");
- auto struct_ty_ptr = ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Owned, struct_ty.clone());
- // - Drop Glue
-
- ::std::vector< ::std::pair<::HIR::Pattern,::HIR::TypeRef> > args;
- if( item.m_markings.has_drop_impl ) {
- // If the type is defined outside the current crate, define as static (to avoid conflicts when we define it)
- if( p.m_path.m_crate_name != m_crate.m_crate_name )
- {
- if( item.m_params.m_types.size() > 0 ) {
- m_of << "static ";
- }
- else {
- m_of << "extern ";
- }
- }
- 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) )
+ if( has_drop_glue )
{
- m_box_glue_todo.push_back( ::std::make_pair( mv$(struct_ty.m_data.as_Path().path.m_data.as_Generic()), &item ) );
- m_of << "static void " << Trans_Mangle(drop_glue_path) << "("; emit_ctype(struct_ty_ptr, FMT_CB(ss, ss << "rv";)); m_of << ");\n";
- return ;
- }
-
- ::MIR::TypeResolve mir_res { sp, m_resolve, FMT_CB(ss, ss << drop_glue_path;), struct_ty_ptr, args, empty_fcn };
- m_mir_res = &mir_res;
- m_of << "static void " << Trans_Mangle(drop_glue_path) << "("; emit_ctype(struct_ty_ptr, FMT_CB(ss, ss << "rv";)); m_of << ") {\n";
+ m_of << "fn " << drop_glue_path << "(&move " << ty << ") {\n";
+ m_of << "\tlet unit: ();\n";
+
+ if( const auto* ity = m_resolve.is_type_owned_box(ty) )
+ {
+ m_of << "\t0: {\n";
+ //ASSERT_BUG(sp, !item.m_markings.has_drop_impl, "Box shouldn't have a Drop impl");
- // If this type has an impl of Drop, call that impl
- if( item.m_markings.has_drop_impl ) {
- m_of << "\t" << Trans_Mangle( ::HIR::Path(struct_ty.clone(), m_resolve.m_lang_Drop, "drop") ) << "(rv);\n";
- }
+ // TODO: This is very specific to the structure of the official liballoc's Box.
+ auto self = ::MIR::LValue::make_Deref({ box$(::MIR::LValue::make_Argument({0})) });
+ auto fld_p_lv = ::MIR::LValue::make_Field({ box$(self), 0 });
+ fld_p_lv = ::MIR::LValue::make_Field({ box$(fld_p_lv), 0 });
+ fld_p_lv = ::MIR::LValue::make_Field({ box$(fld_p_lv), 0 });
- auto self = ::MIR::LValue::make_Deref({ box$(::MIR::LValue::make_Return({})) });
- auto fld_lv = ::MIR::LValue::make_Field({ box$(self), 0 });
- TU_MATCHA( (item.m_data), (e),
- (Unit,
- ),
- (Tuple,
- for(unsigned int i = 0; i < e.size(); i ++)
- {
- const auto& fld = e[i];
- fld_lv.as_Field().field_index = i;
+ if( !m_resolve.type_is_copy(sp, *ity) ) {
+ auto fld_lv = ::MIR::LValue::make_Deref({ box$(fld_p_lv.clone()) });
+ m_of << "\t\t""DROP " << fmt(fld_lv) << ";\n";
+ }
- emit_destructor_call(fld_lv, monomorph(fld.ent), true, 1);
+ auto box_free = ::HIR::GenericPath { m_crate.get_lang_item_path(sp, "box_free"), { ity->clone() } };
+ m_of << "\t\t""CALL unit = " << box_free << "(" << fmt(fld_p_lv) << ") goto 2 else 1\n";
+ m_of << "\t}\n";
+ m_of << "\t1: {\n";
+ m_of << "\t\tDIVERGE\n";
+ m_of << "\t}\n";
+ m_of << "\t2: {\n";
}
- ),
- (Named,
- for(unsigned int i = 0; i < e.size(); i ++)
+ else
{
- const auto& fld = e[i].second;
- fld_lv.as_Field().field_index = i;
+ if( item.m_markings.has_drop_impl ) {
+ m_of << "\tlet nms: &mut " << ty << ";\n";
+ }
+ m_of << "\t0: {\n";
- emit_destructor_call(fld_lv, monomorph(fld.ent), true, 1);
+ if( item.m_markings.has_drop_impl )
+ {
+ m_of << "\t\t""ASSIGN nms = &mut *arg0;\n";
+ m_of << "\t\t""CALL unit = " << ::HIR::Path(ty.clone(), m_resolve.m_lang_Drop, "drop") << "(nms) goto 2 else 1\n";
+ m_of << "\t}\n";
+ m_of << "\t1: {\n";
+ m_of << "\t\tDIVERGE\n";
+ m_of << "\t}\n";
+ m_of << "\t2: {\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)
+ {
+ 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";
+ }
+ }
}
- )
- )
- m_of << "}\n";
-#endif
+ m_of << "\t\t""RETURN\n";
+ m_of << "\t}\n";
+ m_of << "}\n";
+ }
m_mir_res = nullptr;
}
void emit_union(const Span& sp, const ::HIR::GenericPath& p, const ::HIR::Union& item) override
@@ -414,6 +388,7 @@ namespace
MIR_ASSERT(*m_mir_res, repr, "No repr for enum " << ty);
m_of << "type " << p << " {\n";
m_of << "\tSIZE " << repr->size << ", ALIGN " << repr->align << ";\n";
+ // TODO: Drop glue path
for(const auto& e : repr->fields)
{
m_of << "\t" << e.offset << " = " << e.ty << ";\n";
diff --git a/tools/standalone_miri/hir_sim.hpp b/tools/standalone_miri/hir_sim.hpp
index 93d5569c..4b111d3e 100644
--- a/tools/standalone_miri/hir_sim.hpp
+++ b/tools/standalone_miri/hir_sim.hpp
@@ -210,6 +210,9 @@ namespace HIR {
::std::string m_name; // if empty, the path is Generic in m_trait
PathParams m_params;
+ Path()
+ {
+ }
Path(SimplePath sp):
Path(GenericPath(sp))
{
diff --git a/tools/standalone_miri/main.cpp b/tools/standalone_miri/main.cpp
index f060fef0..0d372991 100644
--- a/tools/standalone_miri/main.cpp
+++ b/tools/standalone_miri/main.cpp
@@ -97,8 +97,6 @@ Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> ar
return MIRI_Invoke_Extern(fcn.external.link_name, fcn.external.link_abi, ::std::move(args));
}
- ::std::vector<bool> drop_flags = fcn.m_mir.drop_flags;
-
struct State
{
ModuleTree& modtree;
@@ -106,12 +104,14 @@ Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> ar
Value ret;
::std::vector<Value> args;
::std::vector<Value> locals;
+ ::std::vector<bool> drop_flags;
State(ModuleTree& modtree, const Function& fcn, ::std::vector<Value> args):
modtree(modtree),
fcn(fcn),
ret(fcn.ret_ty),
- args(::std::move(args))
+ args(::std::move(args)),
+ drop_flags(fcn.m_mir.drop_flags)
{
locals.reserve(fcn.m_mir.locals.size());
for(const auto& ty : fcn.m_mir.locals)
@@ -906,7 +906,7 @@ Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> ar
}
} break;
TU_ARM(se.src, Struct, re) {
- throw "TODO";
+ LOG_TODO(stmt);
} break;
}
LOG_DEBUG("- " << new_val);
@@ -915,9 +915,41 @@ Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> ar
case ::MIR::Statement::TAG_Asm:
LOG_TODO(stmt);
break;
- case ::MIR::Statement::TAG_Drop:
- LOG_TODO(stmt);
- break;
+ TU_ARM(stmt, Drop, se) {
+ if( se.flag_idx == ~0u || state.drop_flags.at(se.flag_idx) )
+ {
+ ::HIR::TypeRef ty;
+ auto v = state.get_value_and_type(se.slot, ty);
+ // If an owned borrow, deref to inner
+ // If an array, drop all inners
+ if( !ty.wrappers.empty() )
+ LOG_TODO(stmt << " - " << ty);
+
+ // If a composite, check for drop glue and drop if present
+ if( ty.wrappers.empty() )
+ {
+ if( ty.inner_type == RawType::Composite )
+ {
+ if( ty.composite_type->drop_glue != ::HIR::Path() )
+ {
+ LOG_TODO(stmt << " - " << ty);
+ }
+ else
+ {
+ // No drop glue
+ }
+ }
+ else if( ty.inner_type == RawType::TraitObject )
+ {
+ LOG_TODO(stmt << " - " << ty);
+ }
+ else
+ {
+ // No destructor
+ }
+ }
+ }
+ } break;
case ::MIR::Statement::TAG_SetDropFlag:
LOG_TODO(stmt);
break;
@@ -1098,9 +1130,27 @@ Value MIRI_Invoke_Intrinsic(const ::std::string& name, const ::HIR::PathParams&
{
// Assume is a no-op which returns unit
}
+ else if( name == "offset" )
+ {
+ auto ptr_val = ::std::move(args.at(0));
+ auto& ofs_val = args.at(1);
+
+ auto r = ptr_val.allocation.alloc().get_relocation(0);
+ auto orig_ofs = ptr_val.read_usize(0);
+ auto delta_ofs = ptr_val.read_usize(0);
+ auto new_ofs = orig_ofs + delta_ofs;
+ if(POINTER_SIZE != 8) {
+ new_ofs &= 0xFFFFFFFF;
+ }
+
+
+ ptr_val.write_usize(0, new_ofs);
+ ptr_val.allocation.alloc().relocations.push_back({ 0, r });
+ return ptr_val;
+ }
else
{
- LOG_TODO("Call itrinsic \"" << name << "\"");
+ LOG_TODO("Call intrinsic \"" << name << "\"");
}
return rv;
}
diff --git a/tools/standalone_miri/module_tree.cpp b/tools/standalone_miri/module_tree.cpp
index a457db8e..2fc99bc4 100644
--- a/tools/standalone_miri/module_tree.cpp
+++ b/tools/standalone_miri/module_tree.cpp
@@ -173,16 +173,27 @@ bool Parser::parse_one()
rv.alignment = lex.consume().integer();
lex.check_consume(';');
- // TODO: DST Meta
+ // Drop glue (if present)
+ if( lex.consume_if("DROP") )
+ {
+ rv.drop_glue = parse_path();
+ lex.check_consume(';');
+ }
+ else
+ {
+ // No drop glue
+ }
+
+ // DST Meta type
if( lex.consume_if("DSTMETA") )
{
- //rv->dst_meta = parse_type();
+ rv.dst_meta = parse_type();
lex.check_consume(';');
- throw "TODO";
}
else
{
- //rv->dst_meta = ::HIR::TypeRef::diverge();
+ // Using ! as the metadata type means that the type is Sized (meanwhile, `()` means unsized with no meta)
+ rv.dst_meta = ::HIR::TypeRef::diverge();
}
while( lex.next() != '}' )
diff --git a/tools/standalone_miri/module_tree.hpp b/tools/standalone_miri/module_tree.hpp
index 3489e77e..20e37a51 100644
--- a/tools/standalone_miri/module_tree.hpp
+++ b/tools/standalone_miri/module_tree.hpp
@@ -58,11 +58,17 @@ public:
// struct/union/enum
struct DataType
{
+ // TODO: Store the name of this type for logging?
+
// TODO: Metadata type! (indicates an unsized wrapper)
// TODO: Drop glue
size_t alignment;
size_t size;
+
+ ::HIR::Path drop_glue;
+ ::HIR::TypeRef dst_meta;
+
// Offset and datatype
::std::vector<::std::pair<size_t, ::HIR::TypeRef>> fields;
// Values for variants