git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: opt-in support for Boehm GC (libgc)
6a057a0Andy Arvanitis
pcc/Make.hs+1
@@ -121,6 +121,7 @@ buildMakeActions outputDir filePathMap usePrefix =
121 when (not supportFilesExist) $ do
121 when (not supportFilesExist) $ do
122 writeTextFile (supportDir </> "PureScript.hh") $ B.unpack $(embedFile "pcc/include/purescript.hh")
122 writeTextFile (supportDir </> "PureScript.hh") $ B.unpack $(embedFile "pcc/include/purescript.hh")
123 writeTextFile (supportDir </> "PureScript.cc") $ B.unpack $(embedFile "pcc/include/purescript.cc")
123 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")
124
125
125 let inputPath = dropExtension $ getInputFile mn
126 let inputPath = dropExtension $ getInputFile mn
126 hfile = addExtension inputPath "hh"
127 hfile = addExtension inputPath "hh"
pcc/Makefile+7−2
@@ -24,6 +24,11 @@ override PCCFLAGS += --comments
24override CXXFLAGS += -std=c++11
24override CXXFLAGS += -std=c++11
25override LDFLAGS +=
25override LDFLAGS +=
26
26
27+ifeq ($(USE_GC),yes)
28+ override CXXFLAGS += -DUSE_GC
29+ override LDFLAGS += -lgc
30+endif
31+
27DEBUG := "-DDEBUG -g"
32DEBUG := "-DDEBUG -g"
28RELEASE := "-O3 -flto"
33RELEASE := "-O3 -flto"
29
34
@@ -34,10 +39,10 @@ INCLUDES := -I $(OUTPUT)
34BIN_DIR := $(OUTPUT)/bin
39BIN_DIR := $(OUTPUT)/bin
35
40
36release: codegen
41release: codegen
37− @$(MAKE) $(BIN) CXXFLAGS=$(RELEASE)
42+ @$(MAKE) $(BIN) CXXFLAGS+=$(RELEASE)
38
43
39debug: codegen
44debug: codegen
40− @$(MAKE) $(BIN) CXXFLAGS=$(DEBUG)
45+ @$(MAKE) $(BIN) CXXFLAGS+=$(DEBUG)
41
46
42codegen:
47codegen:
43 @$(PCC) $(PCCFLAGS) --output $(OUTPUT) $(PURESCRIPT_PKG_SRCS) $(PURESCRIPT_SRCS)
48 @$(PCC) $(PCCFLAGS) --output $(OUTPUT) $(PURESCRIPT_PKG_SRCS) $(PURESCRIPT_SRCS)
pcc/include/purescript.cc+1−1
@@ -83,7 +83,7 @@ any::operator const array&() const {
83}
83}
84
84
85auto any::extractPointer() const -> void* {
85auto any::extractPointer() const -> void* {
86− RETURN_VALUE(Type::Pointer, p.get(),)
86+ RETURN_VALUE(Type::Pointer, POINTER_FROM_MEMBER(p),)
87}
87}
88
88
89auto any::unthunkVariant(const any& a) -> const any& {
89auto any::unthunkVariant(const any& a) -> const any& {
pcc/include/purescript.hh+24−16
@@ -25,7 +25,6 @@
25 #define assert(x)
25 #define assert(x)
26#endif
26#endif
27
27
28−#include <memory>
29#include <functional>
28#include <functional>
30#include <string>
29#include <string>
31#include <vector>
30#include <vector>
@@ -33,6 +32,7 @@
33#include <utility>
32#include <utility>
34#include <stdexcept>
33#include <stdexcept>
35#include <iso646.h> // mostly for MS Visual Studio compiler
34#include <iso646.h> // mostly for MS Visual Studio compiler
35+#include "PureScript_GC.hh"
36
36
37namespace PureScript {
37namespace PureScript {
38
38
@@ -80,12 +80,13 @@ class any {
80 };
80 };
81 static constexpr as_thunk unthunk = as_thunk{};
81 static constexpr as_thunk unthunk = as_thunk{};
82
82
83− using map = std::vector<std::pair<const char * const, const any>>;
83+ using map_pair = std::pair<const char * const, const any>;
84+ using map = std::vector<map_pair WITH_ALLOCATOR(map_pair)>;
84− using data = std::vector<any>;
85+ using data = std::vector<any WITH_ALLOCATOR(any)>;
85− using array = std::deque<any>;
86+ using array = std::deque<any WITH_ALLOCATOR(any)>;
86− using fn = auto (*)(const any&) -> any;
87+ using fn = auto (*)(const any&) -> any;
87− using eff_fn = auto (*)() -> any;
88+ using eff_fn = auto (*)() -> any;
88− using thunk = auto (*)(const as_thunk) -> const any&;
89+ using thunk = auto (*)(const as_thunk) -> const any&;
89
90
90 private:
91 private:
91 class closure {
92 class closure {
@@ -122,11 +123,11 @@ class any {
122
123
123 public:
124 public:
124 template <typename T>
125 template <typename T>
125− using shared = std::shared_ptr<T>;
126+ using shared = SHARED_TYPE(T);
126
127
127 template <typename T, typename... Args>
128 template <typename T, typename... Args>
128− inline static auto make_shared(Args&&... args) -> decltype(std::make_shared<T>(std::forward<Args>(args)...)) {
129+ inline static auto make_shared(Args&&... args) -> SHARED_TYPE(T) {
129− return std::make_shared<T>(std::forward<Args>(args)...);
130+ return MAKE_SHARED(T)(std::forward<Args>(args)...);
130 }
131 }
131
132
132 private:
133 private:
@@ -201,8 +202,9 @@ class any {
201 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0) noexcept
202 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0) noexcept
202 : type(Type::Thunk), t(val) {}
203 : type(Type::Thunk), t(val) {}
203
204
204− template <typename T>
205+ template <typename T,
206+ typename = typename std::enable_if<std::is_class<typename std::remove_pointer<T>::type>::value>::type>
205− any(const T& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0) noexcept
207+ any(const T& val, typename std::enable_if<IS_POINTER_TYPE(T)::value>::type* = 0) noexcept
206 : type(Type::Pointer), p(val) {}
208 : type(Type::Pointer), p(val) {}
207
209
208 template <typename T>
210 template <typename T>
@@ -211,8 +213,9 @@ class any {
211
213
212 any(std::nullptr_t) noexcept : type(Type::Pointer), p(nullptr) {}
214 any(std::nullptr_t) noexcept : type(Type::Pointer), p(nullptr) {}
213
215
214− private:
215
216
217+#if !defined(USE_GC)
218+ private:
216 auto copy(const any& other) const noexcept -> void {
219 auto copy(const any& other) const noexcept -> void {
217 if (type & Type::Shared) {
220 if (type & Type::Shared) {
218 new (&p) shared<void>(other.p);
221 new (&p) shared<void>(other.p);
@@ -236,7 +239,6 @@ class any {
236 }
239 }
237
240
238 public:
241 public:
239−
240 any(const any& other) noexcept : type(other.type) {
242 any(const any& other) noexcept : type(other.type) {
241 copy(other);
243 copy(other);
242 }
244 }
@@ -259,11 +261,13 @@ class any {
259 return *this;
261 return *this;
260 }
262 }
261
263
262− any() = delete;
263−
264 ~any() {
264 ~any() {
265 destruct();
265 destruct();
266 }
266 }
267+#endif // !defined(USE_GC)
268+
269+ public:
270+ any() = delete;
267
271
268 auto operator()(const any&) const -> any;
272 auto operator()(const any&) const -> any;
269 auto operator()(const as_thunk) const -> const any&;
273 auto operator()(const as_thunk) const -> const any&;
@@ -384,6 +388,10 @@ inline auto cast(const any& a) ->
384
388
385} // namespace PureScript
389} // namespace PureScript
386
390
391+#undef WITH_ALLOCATOR
392+#undef SHARED_TYPE
393+#undef MAKE_SHARED
394+#undef IS_POINTER_TYPE
387#undef DEFINE_OPERATOR
395#undef DEFINE_OPERATOR
388#undef DEFINE_INT_OPERATOR
396#undef DEFINE_INT_OPERATOR
389#undef DECLARE_COMPARISON_OPERATOR
397#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"
172 (Just $ CppPrimitive "int")
172 (Just $ CppPrimitive "int")
173 []
173 []
174 (CppBlock [ CppUseNamespace "Main"
174 (CppBlock [ CppUseNamespace "Main"
175+ , CppApp (CppVar "INITIALIZE_GC") []
175 , CppApp (CppApp (CppAccessor (CppVar "main") (CppVar "Main"))
176 , CppApp (CppApp (CppAccessor (CppVar "main") (CppVar "Main"))
176 [CppVar unthunkMarkerValue])
177 [CppVar unthunkMarkerValue])
177 []
178 []