git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: opt-in support for Boehm GC (libgc)
commit6a057a0bff32ec813d6bee0c825b9f3f4317dc0c authorAndy Arvanitis <andyarvanitis@gmail.com> dateThu 28 Apr 2016, 16:17 (11 years ago) parent2a4e404
6 files changed+72−19
pcc/Make.hs+1 pcc/Makefile+7−2 pcc/include/purescript.cc+1−1 pcc/include/purescript.hh+24−16 pcc/include/purescript_gc.hh+38 src/Language/PureScript/CodeGen/Cpp/File.hs+1
pcc/Make.hs+1
@@ -121,6 +121,7 @@ buildMakeActions outputDir filePathMap usePrefix =
121121 when (not supportFilesExist) $ do
122122 writeTextFile (supportDir </> "PureScript.hh") $ B.unpack $(embedFile "pcc/include/purescript.hh")
123123 writeTextFile (supportDir </> "PureScript.cc") $ B.unpack $(embedFile "pcc/include/purescript.cc")
124+ writeTextFile (supportDir </> "PureScript_GC.hh") $ B.unpack $(embedFile "pcc/include/purescript_gc.hh")
124125
125126 let inputPath = dropExtension $ getInputFile mn
126127 hfile = addExtension inputPath "hh"
pcc/Makefile+7−2
@@ -24,6 +24,11 @@ override PCCFLAGS += --comments
2424override CXXFLAGS += -std=c++11
2525override LDFLAGS +=
2626
27+ifeq ($(USE_GC),yes)
28+ override CXXFLAGS += -DUSE_GC
29+ override LDFLAGS += -lgc
30+endif
31+
2732DEBUG := "-DDEBUG -g"
2833RELEASE := "-O3 -flto"
2934
@@ -34,10 +39,10 @@ INCLUDES := -I $(OUTPUT)
3439BIN_DIR := $(OUTPUT)/bin
3540
3641release: codegen
37− @$(MAKE) $(BIN) CXXFLAGS=$(RELEASE)
42+ @$(MAKE) $(BIN) CXXFLAGS+=$(RELEASE)
3843
3944debug: codegen
40− @$(MAKE) $(BIN) CXXFLAGS=$(DEBUG)
45+ @$(MAKE) $(BIN) CXXFLAGS+=$(DEBUG)
4146
4247codegen:
4348 @$(PCC) $(PCCFLAGS) --output $(OUTPUT) $(PURESCRIPT_PKG_SRCS) $(PURESCRIPT_SRCS)
pcc/include/purescript.cc+1−1
@@ -83,7 +83,7 @@ any::operator const array&() const {
8383}
8484
8585auto any::extractPointer() const -> void* {
86− RETURN_VALUE(Type::Pointer, p.get(),)
86+ RETURN_VALUE(Type::Pointer, POINTER_FROM_MEMBER(p),)
8787}
8888
8989auto any::unthunkVariant(const any& a) -> const any& {
pcc/include/purescript.hh+24−16
@@ -25,7 +25,6 @@
2525 #define assert(x)
2626#endif
2727
28−#include <memory>
2928#include <functional>
3029#include <string>
3130#include <vector>
@@ -33,6 +32,7 @@
3332#include <utility>
3433#include <stdexcept>
3534#include <iso646.h> // mostly for MS Visual Studio compiler
35+#include "PureScript_GC.hh"
3636
3737namespace PureScript {
3838
@@ -80,12 +80,13 @@ class any {
8080 };
8181 static constexpr as_thunk unthunk = as_thunk{};
8282
83− using map = std::vector<std::pair<const char * const, const any>>;
84− using data = std::vector<any>;
85− using array = std::deque<any>;
86− using fn = auto (*)(const any&) -> any;
87− using eff_fn = auto (*)() -> any;
88− using thunk = auto (*)(const as_thunk) -> const any&;
83+ using map_pair = std::pair<const char * const, const any>;
84+ using map = std::vector<map_pair WITH_ALLOCATOR(map_pair)>;
85+ using data = std::vector<any WITH_ALLOCATOR(any)>;
86+ using array = std::deque<any WITH_ALLOCATOR(any)>;
87+ using fn = auto (*)(const any&) -> any;
88+ using eff_fn = auto (*)() -> any;
89+ using thunk = auto (*)(const as_thunk) -> const any&;
8990
9091 private:
9192 class closure {
@@ -122,11 +123,11 @@ class any {
122123
123124 public:
124125 template <typename T>
125− using shared = std::shared_ptr<T>;
126+ using shared = SHARED_TYPE(T);
126127
127128 template <typename T, typename... Args>
128− inline static auto make_shared(Args&&... args) -> decltype(std::make_shared<T>(std::forward<Args>(args)...)) {
129− return std::make_shared<T>(std::forward<Args>(args)...);
129+ inline static auto make_shared(Args&&... args) -> SHARED_TYPE(T) {
130+ return MAKE_SHARED(T)(std::forward<Args>(args)...);
130131 }
131132
132133 private:
@@ -201,8 +202,9 @@ class any {
201202 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0) noexcept
202203 : type(Type::Thunk), t(val) {}
203204
204− template <typename T>
205− any(const T& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0) noexcept
205+ template <typename T,
206+ typename = typename std::enable_if<std::is_class<typename std::remove_pointer<T>::type>::value>::type>
207+ any(const T& val, typename std::enable_if<IS_POINTER_TYPE(T)::value>::type* = 0) noexcept
206208 : type(Type::Pointer), p(val) {}
207209
208210 template <typename T>
@@ -211,8 +213,9 @@ class any {
211213
212214 any(std::nullptr_t) noexcept : type(Type::Pointer), p(nullptr) {}
213215
214− private:
215216
217+#if !defined(USE_GC)
218+ private:
216219 auto copy(const any& other) const noexcept -> void {
217220 if (type & Type::Shared) {
218221 new (&p) shared<void>(other.p);
@@ -236,7 +239,6 @@ class any {
236239 }
237240
238241 public:
239−
240242 any(const any& other) noexcept : type(other.type) {
241243 copy(other);
242244 }
@@ -259,11 +261,13 @@ class any {
259261 return *this;
260262 }
261263
262− any() = delete;
263−
264264 ~any() {
265265 destruct();
266266 }
267+#endif // !defined(USE_GC)
268+
269+ public:
270+ any() = delete;
267271
268272 auto operator()(const any&) const -> any;
269273 auto operator()(const as_thunk) const -> const any&;
@@ -384,6 +388,10 @@ inline auto cast(const any& a) ->
384388
385389} // namespace PureScript
386390
391+#undef WITH_ALLOCATOR
392+#undef SHARED_TYPE
393+#undef MAKE_SHARED
394+#undef IS_POINTER_TYPE
387395#undef DEFINE_OPERATOR
388396#undef DEFINE_INT_OPERATOR
389397#undef DECLARE_COMPARISON_OPERATOR
pcc/include/purescript_gc.hhnew file+38
@@ -0,0 +1,38 @@
1+///////////////////////////////////////////////////////////////////////////////
2+//
3+// Module : purescript.hh
4+// Copyright : (c) Andy Arvanitis 2016
5+// License : MIT
6+//
7+// Maintainer : Andy Arvanitis <andy.arvanitis@gmail.com>
8+// Stability : experimental
9+// Portability :
10+//
11+// Includes and macros for garbage collection options
12+//
13+///////////////////////////////////////////////////////////////////////////////
14+//
15+#ifndef PureScript_GC_HH
16+#define PureScript_GC_HH
17+
18+#if defined(USE_GC)
19+ #define GC_THREADS
20+ #include <gc/gc_cpp.h>
21+ #include <gc/gc_allocator.h>
22+ #define WITH_ALLOCATOR(T) , traceable_allocator<T>
23+ #define SHARED_TYPE(T) T*
24+ #define MAKE_SHARED(T) new (GC) T
25+ #define IS_POINTER_TYPE(T) std::is_pointer<T>
26+ #define POINTER_FROM_MEMBER(P) P
27+ #define INITIALIZE_GC(_) GC_INIT()
28+#else
29+ #include <memory>
30+ #define WITH_ALLOCATOR(_)
31+ #define SHARED_TYPE(T) std::shared_ptr<T>
32+ #define MAKE_SHARED(T) std::make_shared<T>
33+ #define IS_POINTER_TYPE(T) std::is_assignable<shared<void>,T>
34+ #define POINTER_FROM_MEMBER(P) P.get()
35+ #define INITIALIZE_GC(_)
36+#endif
37+
38+#endif // PureScript_GC_HH
src/Language/PureScript/CodeGen/Cpp/File.hs+1
@@ -172,6 +172,7 @@ nativeMain = CppFunction "main"
172172 (Just $ CppPrimitive "int")
173173 []
174174 (CppBlock [ CppUseNamespace "Main"
175+ , CppApp (CppVar "INITIALIZE_GC") []
175176 , CppApp (CppApp (CppAccessor (CppVar "main") (CppVar "Main"))
176177 [CppVar unthunkMarkerValue])
177178 []