diff options
author | John Hodge <tpg@mutabah.net> | 2018-12-30 07:36:38 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2018-12-30 07:36:38 +0800 |
commit | 6fb11a5af19b91557dba1ca853599596622f56df (patch) | |
tree | b40cf5afde0c0cb312a77c4272233965ce710281 /src | |
parent | e0353e87cda89f33c665e05963d6fd7893972063 (diff) | |
download | mrust-6fb11a5af19b91557dba1ca853599596622f56df.tar.gz |
Codegen C - Add hacky compiler-provided glue
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 2 | ||||
-rw-r--r-- | src/trans/allocator.cpp | 19 | ||||
-rw-r--r-- | src/trans/allocator.hpp | 10 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 85 |
4 files changed, 94 insertions, 22 deletions
diff --git a/src/main.cpp b/src/main.cpp index 1af432b2..782e043f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -638,6 +638,8 @@ int main(int argc, char *argv[]) crate_type = ::AST::Crate::Type::Executable; } + // TODO: For 1.29 executables/dylibs, add oom/panic shims + // Enumerate items to be passed to codegen TransList items = CompilePhase<TransList>("Trans Enumerate", [&]() { switch( crate_type ) diff --git a/src/trans/allocator.cpp b/src/trans/allocator.cpp index 5f61093d..9f5559ae 100644 --- a/src/trans/allocator.cpp +++ b/src/trans/allocator.cpp @@ -12,25 +12,14 @@ #define DEF_METHOD(name, ret) { #name, AllocatorDataTy::ret, sizeof(ALLOCATOR_METHODS_ARGS_##name)/sizeof(AllocatorDataTy), ALLOCATOR_METHODS_ARGS_##name } DEF_METHOD_ARGS(alloc, AllocatorDataTy::Layout) -DEF_METHOD_ARGS(oom, AllocatorDataTy::AllocError) DEF_METHOD_ARGS(dealloc, AllocatorDataTy::Ptr, AllocatorDataTy::Layout) -DEF_METHOD_ARGS(usable_size, AllocatorDataTy::LayoutRef) -DEF_METHOD_ARGS(realloc, AllocatorDataTy::Ptr, AllocatorDataTy::Layout, AllocatorDataTy::Layout) +DEF_METHOD_ARGS(realloc, AllocatorDataTy::Ptr, AllocatorDataTy::Layout, AllocatorDataTy::Usize) DEF_METHOD_ARGS(alloc_zeroed, AllocatorDataTy::Layout) -DEF_METHOD_ARGS(alloc_excess, AllocatorDataTy::Layout) -DEF_METHOD_ARGS(realloc_excess, AllocatorDataTy::Ptr, AllocatorDataTy::Layout, AllocatorDataTy::Layout) -DEF_METHOD_ARGS(grow_in_place, AllocatorDataTy::Ptr, AllocatorDataTy::Layout, AllocatorDataTy::Layout) -DEF_METHOD_ARGS(shrink_in_place, AllocatorDataTy::Ptr, AllocatorDataTy::Layout, AllocatorDataTy::Layout) -const AllocatorMethod ALLOCATOR_METHODS[10] = { +const AllocatorMethod ALLOCATOR_METHODS[4] = { DEF_METHOD(alloc, ResultPtr), - DEF_METHOD(oom, Never), DEF_METHOD(dealloc, Unit), - DEF_METHOD(usable_size, UsizePair), DEF_METHOD(realloc, ResultPtr), - DEF_METHOD(alloc_zeroed, ResultPtr), - DEF_METHOD(alloc_excess, ResultExcess), - DEF_METHOD(realloc_excess, ResultExcess), - DEF_METHOD(grow_in_place, ResultUnit), - DEF_METHOD(shrink_in_place, ResultUnit) + DEF_METHOD(alloc_zeroed, ResultPtr) }; +const size_t NUM_ALLOCATOR_METHODS = sizeof(ALLOCATOR_METHODS)/sizeof(ALLOCATOR_METHODS[0]); diff --git a/src/trans/allocator.hpp b/src/trans/allocator.hpp index 8a4e5186..c124ef57 100644 --- a/src/trans/allocator.hpp +++ b/src/trans/allocator.hpp @@ -9,17 +9,12 @@ enum class AllocatorDataTy { // - Return - Never, // ! Unit, // () ResultPtr, // (..., *mut i8) + *mut u8 - ResultExcess, // (..., *mut i8, *mut i8) + *mut u8 - UsizePair, // (..., *mut usize, *mut usize) + () - ResultUnit, // i8 // - Args Layout, // usize, usize - LayoutRef, // *const Layout [actually *const i8] - AllocError, // *const i8 Ptr, // *mut u8 + Usize, // usize }; struct AllocatorMethod { const char* name; @@ -33,5 +28,6 @@ enum class AllocatorKind { DefaultExe, }; -extern const AllocatorMethod ALLOCATOR_METHODS[10]; +extern const AllocatorMethod ALLOCATOR_METHODS[]; +extern const size_t NUM_ALLOCATOR_METHODS; diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index c6f072fd..710300ce 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -639,6 +639,84 @@ namespace { << "__thread void* mrustc_panic_value;\n" ; } + + // Allocator shims + if( TARGETVER_1_29 ) + { + const char* alloc_prefix = "__rdl_"; + for(size_t i = 0; i < NUM_ALLOCATOR_METHODS; i++) + { + struct H { + static void ty_args(::std::vector<const char*>& out, AllocatorDataTy t) { + switch(t) + { + case AllocatorDataTy::Unit: + case AllocatorDataTy::ResultPtr: // (..., *mut i8) + *mut u8 + throw ""; + // - Args + case AllocatorDataTy::Layout: // usize, usize + out.push_back("uintptr_t"); + out.push_back("uintptr_t"); + break; + case AllocatorDataTy::Ptr: // *mut u8 + out.push_back("int8_t*"); + break; + case AllocatorDataTy::Usize: + out.push_back("uintptr_t"); + break; + } + } + static const char* ty_ret(AllocatorDataTy t) { + switch(t) + { + case AllocatorDataTy::Unit: + return "void"; + case AllocatorDataTy::ResultPtr: // (..., *mut i8) + *mut u8 + return "int8_t*"; + // - Args + case AllocatorDataTy::Layout: // usize, usize + case AllocatorDataTy::Ptr: // *mut u8 + case AllocatorDataTy::Usize: + throw ""; + } + throw ""; + } + static void emit_proto(::std::ostream& os, const AllocatorMethod& method, const char* name_prefix, const ::std::vector<const char*>& args) { + os << H::ty_ret(method.ret) << " " << name_prefix << method.name << "("; + for(size_t j = 0; j < args.size(); j ++) + { + if( j != 0 ) + os << ", "; + os << args[j] << " a" << j; + } + os << ")"; + } + }; + const auto& method = ALLOCATOR_METHODS[i]; + ::std::vector<const char*> args; + for(size_t j = 0; j < method.n_args; j ++) + H::ty_args(args, method.args[j]); + H::emit_proto(m_of, method, "__rust_", args); m_of << " {\n"; + m_of << "\textern "; H::emit_proto(m_of, method, alloc_prefix, args); m_of << ";\n"; + m_of << "\t" << alloc_prefix << method.name << "("; + for(size_t j = 0; j < args.size(); j ++) + { + if( j != 0 ) + m_of << ", "; + m_of << "a" << j; + } + m_of << ");\n"; + m_of << "}\n"; + } + + // TODO: Bind `panic_impl` lang item to the item tagged with `panic_implementation` + // TODO: Bind `oom` lang item to the item tagged with `alloc_error_handler` + // - Can do this in enumerate/auto_impls instead, for better iteraction with enum + // XXX: HACK HACK HACK - This only works with libcore/libstd's current layout + m_of << "uint32_t panic_impl(uintptr_t payload) { extern uint32_t __rust_start_panic(uintptr_t payload); return __rust_start_panic(payload); }\n"; + m_of << "struct s__ZN4core5alloc6Layout_A { uintptr_t a, b; };\n"; + m_of << "void oom_impl(struct s__ZN4core5alloc6Layout_A l) { extern void _ZN3std5alloc8rust_oom(struct s__ZN4core5alloc6Layout_A l); _ZN3std5alloc8rust_oom(l); }\n"; + } } m_of.flush(); @@ -2189,6 +2267,13 @@ namespace { m_of << "}\n"; return; } + else if( item.m_linkage.name.rfind("llvm.", 0) == 0 ) + { + emit_function_header(p, item, params); + m_of << " { abort(); }\n"; + m_mir_res = nullptr; + return ; + } else { m_of << "extern "; |