summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2018-12-30 07:36:38 +0800
committerJohn Hodge <tpg@mutabah.net>2018-12-30 07:36:38 +0800
commit6fb11a5af19b91557dba1ca853599596622f56df (patch)
treeb40cf5afde0c0cb312a77c4272233965ce710281
parente0353e87cda89f33c665e05963d6fd7893972063 (diff)
downloadmrust-6fb11a5af19b91557dba1ca853599596622f56df.tar.gz
Codegen C - Add hacky compiler-provided glue
-rw-r--r--src/main.cpp2
-rw-r--r--src/trans/allocator.cpp19
-rw-r--r--src/trans/allocator.hpp10
-rw-r--r--src/trans/codegen_c.cpp85
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 ";