Last active
December 4, 2018 19:41
-
-
Save lambdageek/64c75b440a7b22092c373b7dc8775fe8 to your computer and use it in GitHub Desktop.
Mono C++ basis header
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "mono-basis.hpp" | |
#include <stdio.h> | |
class X : public mono::alloc::polymorphic_base { | |
public: | |
X () = default; | |
bool get() const { return b; } | |
private: | |
bool b; | |
}; | |
class Y : public X { | |
~Y() override; | |
}; | |
Y::~Y() { | |
printf ("Y destructor %p\n", static_cast<void*>(this)); | |
} | |
int main () | |
{ | |
X* x = mono::new_<Y> (); | |
X** p = mono::new_<X*> (x); | |
printf ("%p\n", static_cast<void*>(x)); | |
mono::delete_ (x); | |
mono::delete_ (p); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all: main | |
.PHONY: all | |
main: main.o | |
clang -o main main.o | |
main.o: main.cpp | |
clang -c -xc++ -std=c++11 -fno-rtti -fno-exceptions -Wall -Wextra -O main.cpp |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _MONO_BASIS_HPP | |
#define _MONO_BASIS_HPP | |
#include <cstdlib> | |
#include <utility> | |
#include <new> | |
namespace mono { | |
namespace alloc { | |
namespace detail { | |
inline | |
void *allocate (std::size_t sz) { | |
return std::malloc (sz); // TODO g_malloc | |
} | |
inline | |
void deallocate (void *ptr) { | |
std::free (ptr); // TODO g_free | |
} | |
} // detail | |
/** | |
* Base class for all classes in the Mono runtime. | |
* This ensures that allocation of new objects uses our preferred allocation functions. | |
*/ | |
class base { | |
public: | |
void* operator new (std::size_t sz) { | |
using mono::alloc::detail::allocate; | |
return allocate (sz); | |
} | |
void* operator new (std::size_t sz, void* ptr) { | |
return ::operator new (sz, ptr); | |
} | |
void operator delete (void *ptr) { | |
using mono::alloc::detail::deallocate; | |
return deallocate (ptr); | |
} | |
}; | |
/** | |
* Base class for all polymorpic type hierarchies in the Mono runtime. | |
* This provides two things: overloaded opreator new and operator delete that use | |
* our preferred allocation functions, and a default virtual destructor. | |
* | |
* It's important to derive polymorphic base classes from polymorphic_base | |
* because GCC and Clang compile multiple symbols for a virtual destructor. | |
* One of them, the D0 "deleting object destructor" causes a dependency on | |
* the global `::operator delete(void*)` even if it is never used. Since | |
* Mono does not link with the C++ runtime library, the mere definition of | |
* a virtual destructor will cause linking errors, unless the class has its | |
* own operator delete. | |
*/ | |
class polymorphic_base : public base { | |
public: | |
virtual ~polymorphic_base () = default; | |
}; | |
} // alloc | |
/** | |
* Use the new_ function to allocate: | |
* class Foo : public mono::alloc::polymorphic_base {} | |
* class Bar : public Foo { public: Bar(int x, double y); } | |
* Foo *foo = mono::new_<Bar> (1, 2.0); | |
* mono::delete_<Foo> (foo); | |
* | |
* Use mono::delete_ to delete objects allocated with new_. | |
* | |
* This template can be used with user-defined classes, as well as with the | |
* builtin types such as 'bool', 'char', 'int', 'Foo*' etc. | |
*/ | |
template <typename T, typename... Args> | |
inline | |
T* new_ (Args&&... args) { | |
void *ptr = mono::alloc::detail::allocate (sizeof (T)); | |
return !ptr ? nullptr : new (ptr) T (std::forward<Args>(args)...); | |
} | |
/** | |
* Use the delete_ function to deallocate objects allocated with mono::new_ | |
* | |
* class Foo : public mono::alloc::polymorphic_base {} | |
* class Bar : public Foo { public: Bar (int x, double y); } | |
* Foo *foo = mono::new_<Bar> (1, 2.0); | |
* mono::delete_ (foo); | |
* | |
*/ | |
template <typename T> | |
inline | |
void delete_ (T* t) { | |
if (t == nullptr) | |
return; | |
void *ptr = static_cast<void*>(t); | |
t->~T (); | |
mono::alloc::detail::deallocate (ptr); | |
} | |
} // mono | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment