summaryrefslogtreecommitdiff
path: root/src/trans/codegen_mmir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/trans/codegen_mmir.cpp')
-rw-r--r--src/trans/codegen_mmir.cpp422
1 files changed, 263 insertions, 159 deletions
diff --git a/src/trans/codegen_mmir.cpp b/src/trans/codegen_mmir.cpp
index 73de19d3..58739805 100644
--- a/src/trans/codegen_mmir.cpp
+++ b/src/trans/codegen_mmir.cpp
@@ -18,6 +18,8 @@
namespace
{
+ size_t PTR_BASE = 0x1000; // See matching value in standalone_miri value.hpp
+
size_t Target_GetSizeOf_Required(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty)
{
size_t size;
@@ -39,47 +41,51 @@ namespace
::std::ostream& operator<<(::std::ostream& os, const Fmt<::MIR::LValue>& x)
{
- auto fmt_lhs = [](::std::ostream& os, const ::MIR::LValue& lv) {
- if( lv.is_Deref() ) {
- os << "(" << fmt(lv) << ")";
- }
- else {
- os << fmt(lv);
- }
- };
- switch(x.e.tag())
+ for(const auto& w : ::reverse(x.e.m_wrappers))
{
- case ::MIR::LValue::TAGDEAD: throw "";
- TU_ARM(x.e, Return, _e) (void)_e;
+ if( w.is_Deref() ) {
+ os << "(*";
+ }
+ }
+ TU_MATCHA( (x.e.m_root), (e),
+ (Return,
os << "RETURN";
- break;
- TU_ARM(x.e, Local, e)
+ ),
+ (Local,
os << "var" << e;
- break;
- TU_ARM(x.e, Argument, e)
- os << "arg" << e.idx;
- break;
- TU_ARM(x.e, Static, e)
+ ),
+ (Argument,
+ os << "arg" << e;
+ ),
+ (Static,
os << e;
- break;
- TU_ARM(x.e, Deref, e)
- os << "*" << fmt(*e.val);
- break;
- TU_ARM(x.e, Field, e) {
- fmt_lhs(os, *e.val);
- // Avoid `0.` existing in the output
- if( e.val->is_Field() || e.val->is_Downcast() )
- os << " ";
- os << "." << e.field_index;
- } break;
- TU_ARM(x.e, Index, e) {
- fmt_lhs(os, *e.val);
- os << "[" << fmt(*e.idx) << "]";
- } break;
- TU_ARM(x.e, Downcast, e) {
- fmt_lhs(os, *e.val);
- os << "@" << e.variant_index;
- } break;
+ )
+ )
+ bool was_num = false;
+ for(const auto& w : x.e.m_wrappers)
+ {
+ bool prev_was_num = was_num; was_num = false;
+ switch(w.tag())
+ {
+ case ::MIR::LValue::Wrapper::TAGDEAD: throw "";
+ TU_ARM(w, Deref, e)
+ os << ")";
+ break;
+ TU_ARM(w, Field, field_index) {
+ // Add a space to prevent accidental float literals
+ if( prev_was_num )
+ os << " ";
+ os << "." << field_index;
+ was_num = true;
+ } break;
+ TU_ARM(w, Index, e) {
+ os << "[" << fmt(::MIR::LValue::new_Local(e)) << "]";
+ } break;
+ TU_ARM(w, Downcast, variant_index) {
+ os << "@" << variant_index;
+ was_num = true;
+ } break;
+ }
}
return os;
}
@@ -112,7 +118,10 @@ namespace
os << " " << v.t;
} break;
TU_ARM(e, ItemAddr, v) {
- os << "ADDROF " << v;
+ os << "ADDROF " << *v;
+ } break;
+ TU_ARM(e, Const, v) {
+ BUG(Span(), "Stray named constant in MIR after cleanup - " << e);
} break;
default:
os << e;
@@ -158,18 +167,18 @@ namespace
CodeGenerator_MonoMir(const ::HIR::Crate& crate, const ::std::string& outfile):
m_crate(crate),
m_resolve(crate),
- m_outfile_path(outfile + ".mir"),
- m_of(m_outfile_path)
+ m_outfile_path(outfile),
+ m_of(m_outfile_path + ".mir")
{
for( const auto& crate : m_crate.m_ext_crates )
{
- m_of << "crate \"" << FmtEscaped(crate.second.m_path) << ".o.mir\";\n";
+ m_of << "crate \"" << FmtEscaped(crate.second.m_path) << ".mir\";\n";
}
}
- void finalise(bool is_executable, const TransOptions& opt) override
+ void finalise(const TransOptions& opt, CodegenOutput out_ty, const ::std::string& hir_file) override
{
- if( is_executable )
+ if( out_ty == CodegenOutput::Executable )
{
m_of << "fn ::main#(isize, *const *const i8): isize {\n";
auto c_start_path = m_resolve.m_crate.get_lang_item_path_opt("mrustc-start");
@@ -190,10 +199,33 @@ namespace
m_of << "\t\tRETURN\n";
m_of << "\t}\n";
m_of << "}\n";
+
+ {
+ // Bind `panic_impl` lang item to the item tagged with `panic_implementation`
+ const auto& panic_impl_path = m_crate.get_lang_item_path(Span(), "mrustc-panic_implementation");
+ m_of << "fn ::panic_impl#(usize): u32 = \"panic_impl\":\"Rust\" {\n";
+ m_of << "\t0: {\n";
+ m_of << "\t\tCALL RETURN = " << panic_impl_path << "(arg0) goto 1 else 2\n";
+ m_of << "\t}\n";
+ m_of << "\t1: { RETURN }\n";
+ m_of << "\t2: { DIVERGE }\n";
+ m_of << "}\n";
+
+ // TODO: OOM impl?
+ }
}
m_of.flush();
m_of.close();
+
+ // HACK! Create the output file, but keep it empty
+ {
+ ::std::ofstream of( m_outfile_path );
+ if( !of.good() )
+ {
+ // TODO: Error?
+ }
+ }
}
@@ -233,14 +265,14 @@ namespace
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 });
+ auto self = ::MIR::LValue::new_Deref( ::MIR::LValue::new_Argument(0) );
+ auto fld_lv = ::MIR::LValue::new_Field(mv$(self), 0);
for(const auto& e : repr->fields)
{
if( m_resolve.type_needs_drop_glue(sp, e.ty) ) {
m_of << "\t\t""DROP " << fmt(fld_lv) << ";\n";
}
- fld_lv.as_Field().field_index += 1;
+ fld_lv.inc_Field();
}
m_of << "\t\t""RETURN\n";
m_of << "\t}\n";
@@ -336,9 +368,9 @@ namespace
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);
+ auto vtable_gp = ::HIR::GenericPath(trait.m_vtable_path);
+ vtable_gp.m_params = te.m_trait.m_path.m_params.clone();
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();
@@ -364,8 +396,8 @@ namespace
};
- // TODO: Generate the drop glue (and determine if there is any)
- bool has_drop_glue = m_resolve.type_needs_drop_glue(sp, ty);
+ // 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);
@@ -396,13 +428,13 @@ namespace
//ASSERT_BUG(sp, !item.m_markings.has_drop_impl, "Box shouldn't have a Drop impl");
// 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::new_Deref( ::MIR::LValue::new_Argument(0) );
+ auto fld_p_lv = ::MIR::LValue::new_Field( mv$(self), 0 );
+ fld_p_lv = ::MIR::LValue::new_Field( mv$(fld_p_lv), 0 );
+ fld_p_lv = ::MIR::LValue::new_Field( mv$(fld_p_lv), 0 );
if( m_resolve.type_needs_drop_glue(sp, *ity) ) {
- auto fld_lv = ::MIR::LValue::make_Deref({ box$(fld_p_lv.clone()) });
+ auto fld_lv = ::MIR::LValue::new_Deref( fld_p_lv.clone() );
m_of << "\t\t""DROP " << fmt(fld_lv) << ";\n";
}
@@ -432,14 +464,14 @@ namespace
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 });
+ auto self = ::MIR::LValue::new_Deref( ::MIR::LValue::new_Argument(0) );
+ auto fld_lv = ::MIR::LValue::new_Field( mv$(self), 0 );
for(const auto& e : repr->fields)
{
if( m_resolve.type_needs_drop_glue(sp, e.ty) ) {
m_of << "\t\t""DROP " << fmt(fld_lv) << ";\n";
}
- fld_lv.as_Field().field_index += 1;
+ fld_lv.inc_Field();
}
}
m_of << "\t\t""RETURN\n";
@@ -448,6 +480,51 @@ namespace
}
m_mir_res = nullptr;
}
+ virtual void emit_constructor_enum(const Span& sp, const ::HIR::GenericPath& var_path, const ::HIR::Enum& item, size_t var_idx)
+ {
+ TRACE_FUNCTION_F(var_path);
+
+ ::HIR::TypeRef tmp;
+ auto monomorph = [&](const auto& x)->const auto& {
+ if( monomorphise_type_needed(x) ) {
+ tmp = monomorphise_type(sp, item.m_params, var_path.m_params, x);
+ m_resolve.expand_associated_types(sp, tmp);
+ return tmp;
+ }
+ else {
+ return x;
+ }
+ };
+
+ auto enum_path = var_path.clone();
+ enum_path.m_path.m_components.pop_back();
+
+ // Create constructor function
+ const auto& var_ty = item.m_data.as_Data().at(var_idx).type;
+ const auto& e = var_ty.m_data.as_Path().binding.as_Struct()->m_data.as_Tuple();
+ m_of << "fn " << var_path << "(";
+ for(unsigned int i = 0; i < e.size(); i ++)
+ {
+ if(i != 0)
+ m_of << ", ";
+ m_of << monomorph(e[i].ent);
+ }
+ m_of << "): " << enum_path << " {\n";
+ m_of << "\tlet var0: " << monomorph(var_ty) << ";\n";
+ m_of << "\t0: {\n";
+ m_of << "\t\tASSIGN var0 = { ";
+ for(unsigned int i = 0; i < e.size(); i ++)
+ {
+ if(i != 0)
+ m_of << ", ";
+ m_of << "arg" << i;
+ }
+ m_of << " }: " << monomorph(var_ty) << ";\n";
+ m_of << "\t\tASSIGN RETURN = VARIANT " << enum_path << " " << var_idx << " var0;\n";
+ m_of << "\t\tRETURN\n";
+ m_of << "\t}\n";
+ m_of << "}";
+ }
void emit_constructor_struct(const Span& sp, const ::HIR::GenericPath& p, const ::HIR::Struct& item) override
{
TRACE_FUNCTION_F(p);
@@ -462,7 +539,7 @@ namespace
return x;
}
};
- // Crate constructor function
+ // Create constructor function
const auto& e = item.m_data.as_Tuple();
m_of << "fn " << p << "(";
for(unsigned int i = 0; i < e.size(); i ++)
@@ -494,10 +571,17 @@ namespace
TRACE_FUNCTION_F(p);
::HIR::TypeRef ty = ::HIR::TypeRef::new_path(p.clone(), &item);
+ bool has_drop_glue = m_resolve.type_needs_drop_glue(sp, ty);
+ auto drop_glue_path = ::HIR::Path(ty.clone(), "drop_glue#");
+
const auto* repr = Target_GetTypeRepr(sp, m_resolve, ty);
MIR_ASSERT(*m_mir_res, repr, "No repr for union " << 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";
@@ -508,28 +592,28 @@ namespace
}
m_of << "}\n";
- // TODO: Drop glue!
-#if 0
- // Drop glue (calls destructor if there is one)
- auto item_ty = ::HIR::TypeRef(p.clone(), &item);
- auto drop_glue_path = ::HIR::Path(item_ty.clone(), "#drop_glue");
- auto item_ptr_ty = ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Owned, item_ty.clone());
- auto drop_impl_path = (item.m_markings.has_drop_impl ? ::HIR::Path(item_ty.clone(), m_resolve.m_lang_Drop, "drop") : ::HIR::Path(::HIR::SimplePath()));
- ::MIR::TypeResolve mir_res { sp, m_resolve, FMT_CB(ss, ss << drop_glue_path;), item_ptr_ty, {}, empty_fcn };
- m_mir_res = &mir_res;
-
- if( item.m_markings.has_drop_impl )
- {
- m_of << "tUNIT " << Trans_Mangle(drop_impl_path) << "(union u_" << Trans_Mangle(p) << "*rv);\n";
- }
-
- m_of << "static void " << Trans_Mangle(drop_glue_path) << "(union u_" << Trans_Mangle(p) << "* rv) {\n";
- if( item.m_markings.has_drop_impl )
+ if( has_drop_glue )
{
- m_of << "\t" << Trans_Mangle(drop_impl_path) << "(rv);\n";
+ m_of << "fn " << drop_glue_path << "(&move " << ty << ") {\n";
+ if( item.m_markings.has_drop_impl ) {
+ m_of << "\tlet nms: &mut " << ty << ";\n";
+ }
+ m_of << "\t0: {\n";
+ 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";
+ }
+ // NOTE: Unions don't drop inner values, but do call the destructor
+ m_of << "\t\tRETURN\n";
+ m_of << "\t}\n";
+ m_of << "}\n";
}
- m_of << "}\n";
-#endif
}
void emit_enum(const Span& sp, const ::HIR::GenericPath& p, const ::HIR::Enum& item) override
@@ -542,11 +626,18 @@ namespace
TRACE_FUNCTION_F(p);
::HIR::TypeRef ty = ::HIR::TypeRef::new_path(p.clone(), &item);
+ // Generate the drop glue (and determine if there is any)
+ bool has_drop_glue = m_resolve.type_needs_drop_glue(sp, ty);
+ auto drop_glue_path = ::HIR::Path(ty.clone(), "drop_glue#");
+
const auto* repr = Target_GetTypeRepr(sp, m_resolve, ty);
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
+ 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";
@@ -591,64 +682,61 @@ namespace
}
m_of << "}\n";
-#if 0
// ---
// - Drop Glue
// ---
- 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());
- auto drop_impl_path = (item.m_markings.has_drop_impl ? ::HIR::Path(struct_ty.clone(), m_resolve.m_lang_Drop, "drop") : ::HIR::Path(::HIR::SimplePath()));
- ::MIR::TypeResolve mir_res { sp, m_resolve, FMT_CB(ss, ss << drop_glue_path;), struct_ty_ptr, {}, empty_fcn };
- m_mir_res = &mir_res;
-
- if( item.m_markings.has_drop_impl )
- {
- m_of << "tUNIT " << Trans_Mangle(drop_impl_path) << "(struct e_" << Trans_Mangle(p) << "*rv);\n";
- }
-
- m_of << "static void " << Trans_Mangle(drop_glue_path) << "(struct e_" << Trans_Mangle(p) << "* rv) {\n";
-
- // If this type has an impl of Drop, call that impl
- if( item.m_markings.has_drop_impl )
- {
- m_of << "\t" << Trans_Mangle(drop_impl_path) << "(rv);\n";
- }
- auto self = ::MIR::LValue::make_Deref({ box$(::MIR::LValue::make_Return({})) });
-
- if( nonzero_path.size() > 0 )
- {
- // TODO: Fat pointers?
- m_of << "\tif( (*rv)._1"; emit_nonzero_path(nonzero_path); m_of << " ) {\n";
- emit_destructor_call( ::MIR::LValue::make_Field({ box$(self), 1 }), monomorph(item.m_data.as_Data()[1].type), false, 2 );
- m_of << "\t}\n";
- }
- else if( const auto* e = item.m_data.opt_Data() )
+ if( has_drop_glue )
{
- auto var_lv =::MIR::LValue::make_Downcast({ box$(self), 0 });
+ m_of << "fn " << drop_glue_path << "(&move " << ty << ") {\n";
+ if( item.m_markings.has_drop_impl ) {
+ m_of << "\tlet nms: &mut " << ty << ";\n";
+ }
+ m_of << "\t0: {\n";
- m_of << "\tswitch(rv->TAG) {\n";
- for(unsigned int var_idx = 0; var_idx < e->size(); var_idx ++)
+ size_t first_drop_bb;
+ if( item.m_markings.has_drop_impl )
{
- var_lv.as_Downcast().variant_index = var_idx;
- m_of << "\tcase " << var_idx << ":\n";
- emit_destructor_call(var_lv, monomorph( (*e)[var_idx].type ), false, 2);
- m_of << "\tbreak;\n";
+ 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";
+ first_drop_bb = 3;
}
- m_of << "\t}\n";
- }
- else
- {
- // Value enum
- // Glue does nothing (except call the destructor, if there is one)
+ else
+ {
+ first_drop_bb = 1;
+ }
+ if( const auto* e = item.m_data.opt_Data() )
+ {
+ m_of << "\t\tSWITCH *arg0 { ";
+ for(unsigned int var_idx = 0; var_idx < e->size(); var_idx ++)
+ {
+ if( var_idx != 0 )
+ {
+ m_of << ", ";
+ }
+ m_of << (first_drop_bb + var_idx);
+ }
+ m_of << " }\n";
+ m_of << "\t}\n";
+ for(unsigned int var_idx = 0; var_idx < e->size(); var_idx ++)
+ {
+ m_of << "\t" << (first_drop_bb+var_idx) << ": {\n";
+ m_of << "\t\tDROP (*arg0)@" << var_idx << ";\n";
+ m_of << "\t\tRETURN\n";
+ m_of << "\t}\n";
+ }
+ }
+ else
+ {
+ m_of << "\t}\n";
+ }
+ m_of << "}\n";
}
- m_of << "}\n";
- if( nonzero_path.size() )
- {
- m_enum_repr_cache.insert( ::std::make_pair( p.clone(), mv$(nonzero_path) ) );
- }
-#endif
m_mir_res = nullptr;
}
struct Reloc {
@@ -656,6 +744,13 @@ namespace
size_t len;
const ::HIR::Path* p;
::std::string bytes;
+
+ static Reloc new_named(size_t ofs, size_t len, const ::HIR::Path* p) {
+ return Reloc { ofs, len, p, "" };
+ }
+ static Reloc new_bytes(size_t ofs, size_t len, ::std::string bytes) {
+ return Reloc { ofs, len, nullptr, ::std::move(bytes) };
+ }
};
void emit_str_byte(uint8_t b) {
if( b == 0 ) {
@@ -845,9 +940,9 @@ namespace
{
ASSERT_BUG(sp, lit.is_String(), ty << " not Literal::String - " << lit);
const auto& s = lit.as_String();
- putsize(0);
+ putsize(PTR_BASE + 0);
putsize(s.size());
- out_relocations.push_back(Reloc { base_ofs, 8, nullptr, s });
+ out_relocations.push_back(Reloc::new_bytes(base_ofs, 8, s));
break;
}
// fall
@@ -856,35 +951,41 @@ namespace
size_t ity_size, ity_align;
Target_GetSizeAndAlignOf(sp, m_resolve, ity, ity_size, ity_align);
bool is_unsized = (ity_size == SIZE_MAX);
- if( lit.is_BorrowPath() )
- {
- putsize(0);
- out_relocations.push_back(Reloc { base_ofs, 8, &lit.as_BorrowPath(), "" });
+
+ TU_MATCH_HDRA( (lit), { )
+ TU_ARMA(BorrowPath, le) {
+ putsize(PTR_BASE);
+ out_relocations.push_back(Reloc::new_named(base_ofs, 8, &le));
if( is_unsized )
{
// TODO: Get the size of the pointed-to array
// OR: Find out the source item type and the target trait.
putsize(0);
}
- break;
- }
- else if( lit.is_Integer() )
- {
- ASSERT_BUG(sp, lit.as_Integer() == 0, "Pointer from integer not 0");
+ }
+ TU_ARMA(Integer, le) {
+ ASSERT_BUG(sp, le == 0, "Pointer from integer not 0");
ASSERT_BUG(sp, ty.m_data.is_Pointer(), "Borrow from integer");
- putsize(0);
+ putsize(le);
if( is_unsized )
{
putsize(0);
}
- break;
+ }
+ TU_ARMA(String, le) {
+ const auto& s = lit.as_String();
+ putsize(PTR_BASE);
+ putsize(s.size());
+ out_relocations.push_back(Reloc::new_bytes(base_ofs, 8, s));
+ }
+ break; default:
+ TODO(sp, "Emit a pointer - " << ty << " from literal " << lit);
}
- TODO(sp, "Pointers - " << ty << " w/ " << lit);
} break;
case ::HIR::TypeRef::Data::TAG_Function:
ASSERT_BUG(sp, lit.is_BorrowPath(), ty << " not Literal::BorrowPath - " << lit);
- putsize(0);
- out_relocations.push_back(Reloc { base_ofs, 8, &lit.as_BorrowPath(), "" });
+ putsize(PTR_BASE);
+ out_relocations.push_back(Reloc::new_named(base_ofs, 8, &lit.as_BorrowPath()));
break;
TU_ARM(ty.m_data, Array, te) {
// What about byte strings?
@@ -936,16 +1037,17 @@ namespace
const size_t ptr_size = Target_GetCurSpec().m_arch.m_pointer_bits / 8;
const auto& trait_path = p.m_data.as_UfcsKnown().trait;
const auto& type = *p.m_data.as_UfcsKnown().type;
+ bool has_drop_glue = m_resolve.type_needs_drop_glue(sp, type);
::HIR::TypeRef vtable_ty;
{
- auto vtable_sp = trait_path.m_path;
- vtable_sp.m_components.back() += "#vtable";
+ const auto& vtable_sp = trait.m_vtable_path;
auto vtable_params = trait_path.m_params.clone();
for(const auto& ty : trait.m_type_indexes) {
auto aty = ::HIR::TypeRef( ::HIR::Path( type.clone(), trait_path.clone(), ty.first ) );
m_resolve.expand_associated_types(sp, aty);
vtable_params.m_types.push_back( mv$(aty) );
+ //vtable_params.m_types.at(ty.second) = ::std::move(aty);
}
const auto& vtable_ref = m_crate.get_struct_by_path(sp, vtable_sp);
vtable_ty = ::HIR::TypeRef( ::HIR::GenericPath(mv$(vtable_sp), mv$(vtable_params)), &vtable_ref );
@@ -956,7 +1058,7 @@ namespace
m_of << "static " << p << ": " << vtable_ty << " = \"";
// - Data
// Drop
- emit_str_usize(0);
+ emit_str_usize(has_drop_glue ? PTR_BASE : 0);
// Align
emit_str_usize(align);
// Size
@@ -964,15 +1066,17 @@ namespace
// Methods
for(unsigned int i = 0; i < trait.m_value_indexes.size(); i ++ )
{
- emit_str_usize(0);
+ emit_str_usize(PTR_BASE);
}
m_of << "\" {";
// - Relocations
auto monomorph_cb_trait = monomorphise_type_get_cb(sp, &type, &trait_path.m_params, nullptr);
// Drop
- // - TODO: Some types don't have drop glue
- m_of << "@0+" << ptr_size << " = " << ::HIR::Path(type.clone(), "drop_glue#") << ", ";
+ if( has_drop_glue )
+ {
+ m_of << "@0+" << ptr_size << " = " << ::HIR::Path(type.clone(), "drop_glue#") << ", ";
+ }
// Methods
for(unsigned int i = 0; i < trait.m_value_indexes.size(); i ++ )
{
@@ -1029,11 +1133,6 @@ namespace
::MIR::TypeResolve mir_res { sp, m_resolve, FMT_CB(ss, ss << p;), ret_type, arg_types, *code };
m_mir_res = &mir_res;
- if( item.m_linkage.name != "" )
- {
- // TODO: Save the linkage name.
- }
-
// - Signature
m_of << "fn " << p << "(";
for(unsigned int i = 0; i < item.m_args.size(); i ++)
@@ -1041,7 +1140,12 @@ namespace
if( i != 0 ) m_of << ", ";
m_of << params.monomorph(m_resolve, item.m_args[i].second);
}
- m_of << "): " << ret_type << " {\n";
+ m_of << "): " << ret_type;
+ if( item.m_linkage.name != "" )
+ {
+ m_of << " = \"" << item.m_linkage.name << "\":\"" << item.m_abi << "\"";
+ }
+ m_of << " {\n";
// - Locals
for(unsigned int i = 0; i < code->locals.size(); i ++) {
DEBUG("var" << i << " : " << code->locals[i]);
@@ -1103,8 +1207,8 @@ namespace
case ::MIR::eBinOp::SUB_OV: m_of << "-^"; break;
case ::MIR::eBinOp::MUL: m_of << "*"; break;
case ::MIR::eBinOp::MUL_OV: m_of << "*^"; break;
- case ::MIR::eBinOp::DIV: m_of << "*"; break;
- case ::MIR::eBinOp::DIV_OV: m_of << "*^"; break;
+ case ::MIR::eBinOp::DIV: m_of << "/"; break;
+ case ::MIR::eBinOp::DIV_OV: m_of << "/^"; break;
case ::MIR::eBinOp::MOD: m_of << "%"; break;
case ::MIR::eBinOp::BIT_OR: m_of << "|"; break;
case ::MIR::eBinOp::BIT_AND:m_of << "&"; break;