git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: GC on by default; rename 'shared' type to 'managed'
9a8e36eAndy Arvanitis
pcc/Makefile+1−1
@@ -24,7 +24,7 @@ override PCCFLAGS += --comments
24override CXXFLAGS += -std=c++11
24override CXXFLAGS += -std=c++11
25override LDFLAGS +=
25override LDFLAGS +=
26
26
27−ifeq ($(USE_GC),yes)
27+ifneq ($(GC),no)
28 override CXXFLAGS += -DUSE_GC
28 override CXXFLAGS += -DUSE_GC
29 override LDFLAGS += -lgc
29 override LDFLAGS += -lgc
30endif
30endif
pcc/include/purescript.hh+44−55
@@ -125,33 +125,24 @@ class any {
125 }
125 }
126 };
126 };
127
127
128− public:
129− template <typename T>
130− using shared = SHARED_TYPE(T);
131−
132− template <typename T, typename... Args>
133− inline static auto make_shared(Args&&... args) -> SHARED_TYPE(T) {
134− return MAKE_SHARED(T)(std::forward<Args>(args)...);
135− }
136−
137 private:
128 private:
138 union {
129 union {
139− mutable thunk t;
130+ mutable thunk t;
140− mutable integer i;
131+ mutable integer i;
141− mutable double d;
132+ mutable double d;
142− mutable char c;
133+ mutable char c;
143− mutable bool b;
134+ mutable bool b;
144− mutable cstring r;
135+ mutable cstring r;
145− mutable fn f;
136+ mutable fn f;
146− mutable eff_fn e;
137+ mutable eff_fn e;
147− mutable void * u;
138+ mutable void * u;
148− mutable shared<std::string> s;
139+ mutable managed<std::string> s;
149− mutable shared<map> m;
140+ mutable managed<map> m;
150− mutable shared<data> v;
141+ mutable managed<data> v;
151− mutable shared<array> a;
142+ mutable managed<array> a;
152− mutable shared<closure> l;
143+ mutable managed<closure> l;
153− mutable shared<eff_closure> k;
144+ mutable managed<eff_closure> k;
154− mutable shared<void> p;
145+ mutable managed<void> p;
155 };
146 };
156
147
157 public:
148 public:
@@ -167,22 +158,22 @@ class any {
167
158
168 template <size_t N>
159 template <size_t N>
169 any(const char (&val)[N]) noexcept : type(Type::StringLiteral), r(val) {}
160 any(const char (&val)[N]) noexcept : type(Type::StringLiteral), r(val) {}
170− any(char * val) : type(Type::String), s(make_shared<std::string>(val)) {}
161+ any(char * val) : type(Type::String), s(make_managed<std::string>(val)) {}
171
162
172− any(const std::string& val) : type(Type::String), s(make_shared<std::string>(val)) {}
163+ any(const std::string& val) : type(Type::String), s(make_managed<std::string>(val)) {}
173− any(std::string&& val) noexcept : type(Type::String), s(make_shared<std::string>(std::move(val))) {}
164+ any(std::string&& val) noexcept : type(Type::String), s(make_managed<std::string>(std::move(val))) {}
174
165
175− any(const shared<std::string>& val) noexcept : type(Type::String), s(val) {}
166+ any(const managed<std::string>& val) noexcept : type(Type::String), s(val) {}
176− any(shared<std::string>&& val) noexcept : type(Type::String), s(std::move(val)) {}
167+ any(managed<std::string>&& val) noexcept : type(Type::String), s(std::move(val)) {}
177
168
178− any(const map& val) : type(Type::Map), m(make_shared<map>(val)) {}
169+ any(const map& val) : type(Type::Map), m(make_managed<map>(val)) {}
179− any(map&& val) noexcept : type(Type::Map), m(make_shared<map>(std::move(val))) {}
170+ any(map&& val) noexcept : type(Type::Map), m(make_managed<map>(std::move(val))) {}
180
171
181− any(const data& val) : type(Type::Data), v(make_shared<data>(val)) {}
172+ any(const data& val) : type(Type::Data), v(make_managed<data>(val)) {}
182− any(data&& val) noexcept : type(Type::Data), v(make_shared<data>(std::move(val))) {}
173+ any(data&& val) noexcept : type(Type::Data), v(make_managed<data>(std::move(val))) {}
183
174
184− any(const array& val) : type(Type::Array), a(make_shared<array>(val)) {}
175+ any(const array& val) : type(Type::Array), a(make_managed<array>(val)) {}
185− any(array&& val) noexcept : type(Type::Array), a(make_shared<array>(std::move(val))) {}
176+ any(array&& val) noexcept : type(Type::Array), a(make_managed<array>(std::move(val))) {}
186
177
187 template <typename T>
178 template <typename T>
188 any(const T& val, typename std::enable_if<std::is_convertible<T,fn>::value>::type* = 0) noexcept
179 any(const T& val, typename std::enable_if<std::is_convertible<T,fn>::value>::type* = 0) noexcept
@@ -191,7 +182,7 @@ class any {
191 template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
182 template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
192 !std::is_convertible<T,fn>::value>::type>
183 !std::is_convertible<T,fn>::value>::type>
193 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&)>,T>::value>::type* = 0)
184 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any(const any&)>,T>::value>::type* = 0)
194− : type(Type::Closure), l(make_shared<_closure<T>>(val)) {}
185+ : type(Type::Closure), l(make_managed<_closure<T>>(val)) {}
195
186
196 template <typename T>
187 template <typename T>
197 any(const T& val, typename std::enable_if<std::is_convertible<T,eff_fn>::value>::type* = 0) noexcept
188 any(const T& val, typename std::enable_if<std::is_convertible<T,eff_fn>::value>::type* = 0) noexcept
@@ -201,7 +192,7 @@ class any {
201 typename = typename std::enable_if<!std::is_same<any,T>::value &&
192 typename = typename std::enable_if<!std::is_same<any,T>::value &&
202 !std::is_convertible<T,eff_fn>::value>::type>
193 !std::is_convertible<T,eff_fn>::value>::type>
203 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any()>,T>::value>::type* = 0)
194 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any()>,T>::value>::type* = 0)
204− : type(Type::EffClosure), k(make_shared<_eff_closure<T>>(val)) {}
195+ : type(Type::EffClosure), k(make_managed<_eff_closure<T>>(val)) {}
205
196
206 template <typename T>
197 template <typename T>
207 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0) noexcept
198 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0) noexcept
@@ -213,7 +204,7 @@ class any {
213 : type(Type::Pointer), p(val) {}
204 : type(Type::Pointer), p(val) {}
214
205
215 template <typename T>
206 template <typename T>
216− any(T&& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0) noexcept
207+ any(T&& val, typename std::enable_if<std::is_assignable<managed<void>,T>::value>::type* = 0) noexcept
217 : type(Type::Pointer), p(std::move(val)) {}
208 : type(Type::Pointer), p(std::move(val)) {}
218
209
219 // Explicit void* to raw pointer value
210 // Explicit void* to raw pointer value
@@ -253,13 +244,13 @@ class any {
253 case Type::EffFunction: e = other.e; break;
244 case Type::EffFunction: e = other.e; break;
254 case Type::RawPointer: u = other.u; break;
245 case Type::RawPointer: u = other.u; break;
255
246
256− case Type::String: new (&s) shared<std::string>(move_if_rvalue<T>(other.s)); break;
247+ case Type::String: new (&s) managed<std::string>(move_if_rvalue<T>(other.s)); break;
257− case Type::Map: new (&m) shared<map>(move_if_rvalue<T>(other.m)); break;
248+ case Type::Map: new (&m) managed<map>(move_if_rvalue<T>(other.m)); break;
258− case Type::Data: new (&v) shared<data>(move_if_rvalue<T>(other.v)); break;
249+ case Type::Data: new (&v) managed<data>(move_if_rvalue<T>(other.v)); break;
259− case Type::Array: new (&a) shared<array>(move_if_rvalue<T>(other.a)); break;
250+ case Type::Array: new (&a) managed<array>(move_if_rvalue<T>(other.a)); break;
260− case Type::Closure: new (&l) shared<closure>(move_if_rvalue<T>(other.l)); break;
251+ case Type::Closure: new (&l) managed<closure>(move_if_rvalue<T>(other.l)); break;
261− case Type::EffClosure: new (&k) shared<eff_closure>(move_if_rvalue<T>(other.k)); break;
252+ case Type::EffClosure: new (&k) managed<eff_closure>(move_if_rvalue<T>(other.k)); break;
262− case Type::Pointer: new (&p) shared<void>(move_if_rvalue<T>(other.p)); break;
253+ case Type::Pointer: new (&p) managed<void>(move_if_rvalue<T>(other.p)); break;
263
254
264 default: assert(false && "Bad 'any' type"); break;
255 default: assert(false && "Bad 'any' type"); break;
265 }
256 }
@@ -267,13 +258,13 @@ class any {
267
258
268 auto destruct() -> void {
259 auto destruct() -> void {
269 switch (type) {
260 switch (type) {
270− case Type::String: s.~shared<std::string>(); break;
261+ case Type::String: s.~managed<std::string>(); break;
271− case Type::Map: m.~shared<map>(); break;
262+ case Type::Map: m.~managed<map>(); break;
272− case Type::Data: v.~shared<data>(); break;
263+ case Type::Data: v.~managed<data>(); break;
273− case Type::Array: a.~shared<array>(); break;
264+ case Type::Array: a.~managed<array>(); break;
274− case Type::Closure: l.~shared<closure>(); break;
265+ case Type::Closure: l.~managed<closure>(); break;
275− case Type::EffClosure: k.~shared<eff_closure>(); break;
266+ case Type::EffClosure: k.~managed<eff_closure>(); break;
276− case Type::Pointer: p.~shared<void>(); break;
267+ case Type::Pointer: p.~managed<void>(); break;
277
268
278 default: break;
269 default: break;
279 }
270 }
@@ -442,8 +433,6 @@ inline auto cast(const any& a) ->
442} // namespace PureScript
433} // namespace PureScript
443
434
444#undef WITH_ALLOCATOR
435#undef WITH_ALLOCATOR
445−#undef SHARED_TYPE
446−#undef MAKE_SHARED
447#undef IS_POINTER_TYPE
436#undef IS_POINTER_TYPE
448#undef DEFINE_OPERATOR
437#undef DEFINE_OPERATOR
449#undef DEFINE_INT_OPERATOR
438#undef DEFINE_INT_OPERATOR
pcc/include/purescript_gc.hh+26−5
@@ -20,19 +20,40 @@
20 #include <gc/gc_cpp.h>
20 #include <gc/gc_cpp.h>
21 #include <gc/gc_allocator.h>
21 #include <gc/gc_allocator.h>
22 #define WITH_ALLOCATOR(T) , traceable_allocator<T>
22 #define WITH_ALLOCATOR(T) , traceable_allocator<T>
23− #define SHARED_TYPE(T) T*
23+ #define MANAGED_TYPE(T) T*
24− #define MAKE_SHARED(T) new (GC) T
24+ #define MAKE_MANAGED(T) new (GC) T
25+ #define MAKE_MANAGED_FINALIZED(T) new (GC, [](void* p, void*){ static_cast<T*>(p)->~T(); }) T
25 #define IS_POINTER_TYPE(T) std::is_pointer<T>
26 #define IS_POINTER_TYPE(T) std::is_pointer<T>
26 #define POINTER_FROM_MEMBER(P) P
27 #define POINTER_FROM_MEMBER(P) P
27 #define INITIALIZE_GC(_) GC_INIT()
28 #define INITIALIZE_GC(_) GC_INIT()
28#else
29#else
29 #include <memory>
30 #include <memory>
30 #define WITH_ALLOCATOR(_)
31 #define WITH_ALLOCATOR(_)
31− #define SHARED_TYPE(T) std::shared_ptr<T>
32+ #define MANAGED_TYPE(T) std::shared_ptr<T>
32− #define MAKE_SHARED(T) std::make_shared<T>
33+ #define MAKE_MANAGED(T) std::make_shared<T>
34+ #define MAKE_MANAGED_FINALIZED(T) MAKE_MANAGED(T)
33− #define IS_POINTER_TYPE(T) std::is_assignable<shared<void>,T>
35+ #define IS_POINTER_TYPE(T) std::is_assignable<managed<void>,T>
34 #define POINTER_FROM_MEMBER(P) P.get()
36 #define POINTER_FROM_MEMBER(P) P.get()
35 #define INITIALIZE_GC(_)
37 #define INITIALIZE_GC(_)
36#endif
38#endif
37
39
40+namespace PureScript {
41+ template <typename T>
42+ using managed = MANAGED_TYPE(T);
43+
44+ template <typename T, typename... Args>
45+ inline static auto make_managed(Args&&... args) -> MANAGED_TYPE(T) {
46+ return MAKE_MANAGED(T)(std::forward<Args>(args)...);
47+ }
48+
49+ template <typename T, typename... Args>
50+ inline static auto make_managed_and_finalized(Args&&... args) -> MANAGED_TYPE(T) {
51+ return MAKE_MANAGED_FINALIZED(T)(std::forward<Args>(args)...);
52+ }
53+}
54+
55+#undef MANAGED_TYPE
56+#undef MAKE_MANAGED
57+#undef MAKE_MANAGED_FINALIZED
58+
38#endif // PureScript_GC_HH
59#endif // PureScript_GC_HH