diff options
author | John Hodge <tpg@ucc.asn.au> | 2018-06-03 14:57:05 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2018-06-03 14:57:05 +0800 |
commit | bf8f8b4b4a9fe273451be59f68acafbe61968b83 (patch) | |
tree | 82993550cb3c88de0edbd55d79e4ea8e8cefffac /src/trans/codegen_mmir.cpp | |
parent | 39b3cf53798683e496804f8322da2254b10850f4 (diff) | |
parent | a7fb27789a2b34543851d207120e2c0001ee9c27 (diff) | |
download | mrust-bf8f8b4b4a9fe273451be59f68acafbe61968b83.tar.gz |
Merge branch 'master' of https://github.com/thepowersgang/mrustc
Diffstat (limited to 'src/trans/codegen_mmir.cpp')
-rw-r--r-- | src/trans/codegen_mmir.cpp | 193 |
1 files changed, 152 insertions, 41 deletions
diff --git a/src/trans/codegen_mmir.cpp b/src/trans/codegen_mmir.cpp index faa3598d..3347606c 100644 --- a/src/trans/codegen_mmir.cpp +++ b/src/trans/codegen_mmir.cpp @@ -157,7 +157,7 @@ namespace { if( is_executable ) { - m_of << "fn ::main#(i32, *const *const i8): i32 {\n"; + 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"); if( c_start_path == ::HIR::SimplePath() ) { @@ -281,6 +281,7 @@ namespace case ::HIR::StructMarkings::DstType::TraitObject: return MetadataType::TraitObject; } + throw ""; } break; TU_ARM(te.binding, Union, tpb) return MetadataType::None; @@ -433,6 +434,43 @@ namespace } m_mir_res = nullptr; } + void emit_constructor_struct(const Span& sp, const ::HIR::GenericPath& p, const ::HIR::Struct& item) override + { + TRACE_FUNCTION_F(p); + ::HIR::TypeRef tmp; + auto monomorph = [&](const auto& x)->const auto& { + if( monomorphise_type_needed(x) ) { + tmp = monomorphise_type(sp, item.m_params, p.m_params, x); + m_resolve.expand_associated_types(sp, tmp); + return tmp; + } + else { + return x; + } + }; + // Crate constructor function + const auto& e = item.m_data.as_Tuple(); + m_of << "fn " << p << "("; + for(unsigned int i = 0; i < e.size(); i ++) + { + if(i != 0) + m_of << ", "; + m_of << monomorph(e[i].ent); + } + m_of << "): " << p << " {\n"; + m_of << "\t0: {\n"; + m_of << "\t\tASSIGN RETURN = { "; + for(unsigned int i = 0; i < e.size(); i ++) + { + if(i != 0) + m_of << ", "; + m_of << "arg" << i; + } + m_of << " }: " << p << ";\n"; + m_of << "\t\tRETURN\n"; + m_of << "\t}\n"; + m_of << "}\n"; + } void emit_union(const Span& sp, const ::HIR::GenericPath& p, const ::HIR::Union& item) override { ::MIR::Function empty_fcn; @@ -452,7 +490,7 @@ namespace } for(const auto& e : repr->fields) { - m_of << "\t" << "#" << (&e - repr->fields.data()) << ";\n"; + m_of << "\t" << "#" << (&e - repr->fields.data()) << " =" << (&e - repr->fields.data()) << ";\n"; } m_of << "}\n"; @@ -605,47 +643,50 @@ namespace const ::HIR::Path* p; ::std::string bytes; }; + void emit_str_byte(uint8_t b) { + if( b == 0 ) { + m_of << "\\0"; + } + else if( b == '\\' ) { + m_of << "\\\\"; + } + else if( b == '"' ) { + m_of << "\\\""; + } + else if( ' ' <= b && b <= 'z' && b != '\\' ) { + m_of << b; + } + else if( b < 16 ) { + m_of << "\\x0" << ::std::hex << int(b) << ::std::dec; + } + else { + m_of << "\\x" << ::std::hex << int(b) << ::std::dec; + } + } + void emit_str_u32(uint32_t v) { + emit_str_byte(v & 0xFF); + emit_str_byte(v >> 8); + emit_str_byte(v >> 16); + emit_str_byte(v >> 24); + } + void emit_str_usize(uint64_t v) { + if( Target_GetCurSpec().m_arch.m_pointer_bits == 64 ) { + emit_str_u32(v ); + emit_str_u32(v >> 32); + } + else if( Target_GetCurSpec().m_arch.m_pointer_bits == 64 ) { + emit_str_u32(v ); + } + else { + emit_str_u32(v ); + } + } void emit_literal_as_bytes(const ::HIR::Literal& lit, const ::HIR::TypeRef& ty, ::std::vector<Reloc>& out_relocations, size_t base_ofs) { TRACE_FUNCTION_F(lit << ", " << ty); - auto putb = [&](uint8_t b) { - if( b == 0 ) { - m_of << "\\0"; - } - else if( b == '\\' ) { - m_of << "\\\\"; - } - else if( b == '"' ) { - m_of << "\\\""; - } - else if( ' ' <= b && b <= 'z' && b != '\\' ) { - m_of << b; - } - else if( b < 16 ) { - m_of << "\\x0" << ::std::hex << int(b) << ::std::dec; - } - else { - m_of << "\\x" << ::std::hex << int(b) << ::std::dec; - } - }; - auto putu32 = [&](uint32_t v) { - putb(v & 0xFF); - putb(v >> 8); - putb(v >> 16); - putb(v >> 24); - }; - auto putsize = [&](uint64_t v) { - if( Target_GetCurSpec().m_arch.m_pointer_bits == 64 ) { - putu32(v ); - putu32(v >> 32); - } - else if( Target_GetCurSpec().m_arch.m_pointer_bits == 64 ) { - putu32(v ); - } - else { - putu32(v ); - } - }; + auto putb = [&](uint8_t b) { emit_str_byte(b); }; + auto putu32 = [&](uint32_t v) { emit_str_u32(v); }; + auto putsize = [&](uint64_t v) { emit_str_usize(v); }; switch(ty.m_data.tag()) { case ::HIR::TypeRef::Data::TAGDEAD: throw ""; @@ -877,6 +918,69 @@ namespace m_mir_res = nullptr; } + void emit_vtable(const ::HIR::Path& p, const ::HIR::Trait& trait) override + { + ::MIR::Function empty_fcn; + ::MIR::TypeResolve top_mir_res { sp, m_resolve, FMT_CB(ss, ss << "vtable " << p;), ::HIR::TypeRef(), {}, empty_fcn }; + + 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; + + ::HIR::TypeRef vtable_ty; + { + auto vtable_sp = trait_path.m_path; + vtable_sp.m_components.back() += "#vtable"; + 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) ); + } + 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 ); + } + + size_t size, align; + MIR_ASSERT(*m_mir_res, Target_GetSizeAndAlignOf(sp, m_resolve, type, size, align), "Unexpected generic? " << type); + m_of << "static " << p << ": " << vtable_ty << " = \""; + // - Data + // Drop + emit_str_usize(0); + // Align + emit_str_usize(align); + // Size + emit_str_usize(size); + // Methods + for(unsigned int i = 0; i < trait.m_value_indexes.size(); i ++ ) + { + emit_str_usize(0); + } + 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#") << ", "; + // Methods + for(unsigned int i = 0; i < trait.m_value_indexes.size(); i ++ ) + { + // Find the corresponding vtable entry + for(const auto& m : trait.m_value_indexes) + { + if( m.second.first != 3+i ) + continue ; + + //MIR_ASSERT(*m_mir_res, tr.m_values.at(m.first).is_Function(), "TODO: Handle generating vtables with non-function items"); + DEBUG("- " << m.second.first << " = " << m.second.second << " :: " << m.first); + + auto gpath = monomorphise_genericpath_with(sp, m.second.second, monomorph_cb_trait, false); + m_of << "@" << (3 + i) * ptr_size << "+" << ptr_size << " = " << ::HIR::Path(type.clone(), mv$(gpath), m.first) << ", "; + } + } + m_of << "};\n"; + } void emit_function_ext(const ::HIR::Path& p, const ::HIR::Function& item, const Trans_Params& params) override { ::MIR::Function empty_fcn; @@ -915,6 +1019,12 @@ 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 ++) { @@ -922,6 +1032,7 @@ namespace m_of << params.monomorph(m_resolve, item.m_args[i].second); } m_of << "): " << ret_type << " {\n"; + // - Locals for(unsigned int i = 0; i < code->locals.size(); i ++) { DEBUG("var" << i << " : " << code->locals[i]); m_of << "\tlet var" << i << ": " << code->locals[i] << ";\n"; @@ -930,7 +1041,7 @@ namespace m_of << "\tlet df" << i << " = " << code->drop_flags[i] << ";\n"; } - + for(unsigned int i = 0; i < code->blocks.size(); i ++) { TRACE_FUNCTION_F(p << " bb" << i); |