git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Clean up structure of runtime classes
9eb0b93Andy Arvanitis
runtime/purescript.h+94−87
@@ -27,8 +27,8 @@ namespace purescript {
27
27
28 using std::string;
28 using std::string;
29
29
30+ class boxed {
30− class boxed : public std::shared_ptr<void> {
31+ std::shared_ptr<void> shared;
31−
32 public:
32 public:
33 using fn_t = std::function<boxed(const boxed&)>;
33 using fn_t = std::function<boxed(const boxed&)>;
34 using eff_fn_t = std::function<boxed(void)>;
34 using eff_fn_t = std::function<boxed(void)>;
@@ -36,102 +36,163 @@ namespace purescript {
36 using array_t = std::deque<boxed>;
36 using array_t = std::deque<boxed>;
37
37
38 public:
38 public:
39− using std::shared_ptr<void>::shared_ptr;
39+ boxed() noexcept : shared() {}
40+ boxed(const std::nullptr_t) noexcept : shared() {}
40
41
41− boxed() noexcept : std::shared_ptr<void>() {}
42+ template <typename T>
42− boxed(const std::nullptr_t) noexcept : std::shared_ptr<void>() {}
43+ boxed(std::shared_ptr<T>&& other) : shared(std::move(other)) {}
44+
45+ template <typename T>
43− boxed(const std::shared_ptr<void>& p) : std::shared_ptr<void>::shared_ptr(p) {}
46+ boxed(const std::shared_ptr<T>& other) : shared(other) {}
47+
44− boxed(const int n) : std::shared_ptr<void>(std::make_shared<int>(n)) {}
48+ boxed(const int n) : shared(std::make_shared<int>(n)) {}
49+
45− boxed(const long n) : std::shared_ptr<void>(std::make_shared<int>(static_cast<int>(n))) {
50+ boxed(const long n) : shared(std::make_shared<int>(static_cast<int>(n))) {
46#if !defined(NDEBUG) // if debug build
51#if !defined(NDEBUG) // if debug build
47 if (n < std::numeric_limits<int>::min() || n > std::numeric_limits<int>::max()) {
52 if (n < std::numeric_limits<int>::min() || n > std::numeric_limits<int>::max()) {
48 throw std::runtime_error("integer out of range");
53 throw std::runtime_error("integer out of range");
49 }
54 }
50#endif // !defined(NDEBUG)
55#endif // !defined(NDEBUG)
51 }
56 }
57+
52− boxed(const unsigned long n) : std::shared_ptr<void>(std::make_shared<int>(static_cast<int>(n))) {
58+ boxed(const unsigned long n) : shared(std::make_shared<int>(static_cast<int>(n))) {
53#if !defined(NDEBUG) // if debug build
59#if !defined(NDEBUG) // if debug build
54 if (n > std::numeric_limits<int>::max()) {
60 if (n > std::numeric_limits<int>::max()) {
55 throw std::runtime_error("integer out of range");
61 throw std::runtime_error("integer out of range");
56 }
62 }
57#endif // !defined(NDEBUG)
63#endif // !defined(NDEBUG)
58 }
64 }
65+
59− boxed(const double n) : std::shared_ptr<void>(std::make_shared<double>(n)) {}
66+ boxed(const double n) : shared(std::make_shared<double>(n)) {}
60− boxed(const bool b) : std::shared_ptr<void>(std::make_shared<bool>(b)) {}
67+ boxed(const bool b) : shared(std::make_shared<bool>(b)) {}
61− boxed(const char s[]) : std::shared_ptr<void>(std::make_shared<string>(s)) {}
68+ boxed(const char s[]) : shared(std::make_shared<string>(s)) {}
62− boxed(string&& s) : std::shared_ptr<void>(std::make_shared<string>(std::move(s))) {}
69+ boxed(string&& s) : shared(std::make_shared<string>(std::move(s))) {}
63− boxed(const string& s) : std::shared_ptr<void>(std::make_shared<string>(s)) {}
70+ boxed(const string& s) : shared(std::make_shared<string>(s)) {}
64− boxed(array_t&& l) : std::shared_ptr<void>(std::make_shared<array_t>(std::move(l))) {}
71+ boxed(array_t&& l) : shared(std::make_shared<array_t>(std::move(l))) {}
65− boxed(const array_t& l) : std::shared_ptr<void>(std::make_shared<array_t>(l)) {}
72+ boxed(const array_t& l) : shared(std::make_shared<array_t>(l)) {}
66− boxed(dict_t&& m) : std::shared_ptr<void>(std::make_shared<dict_t>(std::move(m))) {}
73+ boxed(dict_t&& m) : shared(std::make_shared<dict_t>(std::move(m))) {}
67− boxed(const dict_t& m) : std::shared_ptr<void>(std::make_shared<dict_t>(m)) {}
74+ boxed(const dict_t& m) : shared(std::make_shared<dict_t>(m)) {}
68
75
69 template <typename T,
76 template <typename T,
70 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
77 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
71 boxed(const T& f,
78 boxed(const T& f,
72 typename std::enable_if<std::is_assignable<std::function<boxed(boxed)>,T>::value>::type* = 0)
79 typename std::enable_if<std::is_assignable<std::function<boxed(boxed)>,T>::value>::type* = 0)
73− : std::shared_ptr<void>(std::make_shared<fn_t>(f)) {
80+ : shared(std::make_shared<fn_t>(f)) {
74 }
81 }
75
82
76 template <typename T,
83 template <typename T,
77 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
84 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
78 boxed(const T& f,
85 boxed(const T& f,
79 typename std::enable_if<std::is_assignable<std::function<boxed(void)>,T>::value>::type* = 0)
86 typename std::enable_if<std::is_assignable<std::function<boxed(void)>,T>::value>::type* = 0)
80− : std::shared_ptr<void>(std::make_shared<eff_fn_t>(f)) {
87+ : shared(std::make_shared<eff_fn_t>(f)) {
88+ }
89+
90+ inline auto get() const noexcept -> void * {
91+ return shared.get();
81 }
92 }
82
93
83 auto operator()(const boxed& arg) const -> boxed {
94 auto operator()(const boxed& arg) const -> boxed {
84− auto& f = *static_cast<fn_t*>(get());
95+ auto& f = *static_cast<fn_t*>(shared.get());
85 return f(arg);
96 return f(arg);
86 }
97 }
87
98
88 auto operator()() const -> boxed {
99 auto operator()() const -> boxed {
89− auto& f = *static_cast<eff_fn_t*>(get());
100+ auto& f = *static_cast<eff_fn_t*>(shared.get());
90 return f();
101 return f();
91 }
102 }
92
103
93 auto operator[](const char key[]) const -> const boxed& {
104 auto operator[](const char key[]) const -> const boxed& {
94− return (*static_cast<const dict_t*>(get()))[key];
105+ return (*static_cast<const dict_t*>(shared.get()))[key];
95 }
106 }
96
107
97 auto operator[](const char key[]) -> boxed& {
108 auto operator[](const char key[]) -> boxed& {
98− return (*static_cast<dict_t*>(get()))[key];
109+ return (*static_cast<dict_t*>(shared.get()))[key];
99 }
110 }
100
111
101#if !defined(NDEBUG) // if debug build
112#if !defined(NDEBUG) // if debug build
102 auto operator[](const int index) const -> const boxed& {
113 auto operator[](const int index) const -> const boxed& {
103− return static_cast<const array_t*>(get())->at(index);
114+ return static_cast<const array_t*>(shared.get())->at(index);
104 }
115 }
105
116
106 auto operator[](const int index) -> boxed& {
117 auto operator[](const int index) -> boxed& {
107− return static_cast<array_t*>(get())->at(index);
118+ return static_cast<array_t*>(shared.get())->at(index);
108 }
119 }
109#else // not debug build
120#else // not debug build
110 auto operator[](const int index) const -> const boxed& {
121 auto operator[](const int index) const -> const boxed& {
111− return (*static_cast<const array_t*>(get()))[index];
122+ return (*static_cast<const array_t*>(shared.get()))[index];
112 }
123 }
113
124
114 auto operator[](const int index) -> boxed& {
125 auto operator[](const int index) -> boxed& {
115− return (*static_cast<array_t*>(get()))[index];
126+ return (*static_cast<array_t*>(shared.get()))[index];
116 }
127 }
117#endif // !defined(NDEBUG)
128#endif // !defined(NDEBUG)
118
129
119 class weak {
130 class weak {
120− std::weak_ptr<void> ptr;
131+ std::weak_ptr<void> wptr;
121
132
122 public:
133 public:
123 weak() = delete;
134 weak() = delete;
124− weak(boxed& b) : ptr(b) {}
135+ weak(boxed& b) : wptr(b.shared) {}
125
136
126 operator boxed() const {
137 operator boxed() const {
127#if defined(NDEBUG)
138#if defined(NDEBUG)
128− return ptr.lock();
139+ return wptr.lock();
129#else
140#else
130− return static_cast<std::shared_ptr<void>>(ptr);
141+ return static_cast<std::shared_ptr<void>>(wptr);
131#endif
142#endif
132 }
143 }
133
144
134− }; // class weak
145+ }; // class boxed::weak
146+
147+ class ref {
148+ std::shared_ptr<boxed> sptr;
149+ std::shared_ptr<boxed::weak> wptr;
150+
151+ public:
152+ ref() : sptr(std::make_shared<boxed>())
153+ , wptr(std::make_shared<boxed::weak>(*sptr)) {}
154+
155+ operator const boxed&() const {
156+ return *sptr;
157+ }
158+
159+ operator boxed&() {
160+ return *sptr;
161+ }
162+
163+ auto operator()() const -> boxed {
164+ return (*sptr)();
165+ }
166+
167+ auto operator()(const boxed& arg) const -> boxed {
168+ return (*sptr)(arg);
169+ }
170+
171+ template <typename T>
172+ auto operator=(T&& right) -> ref& {
173+ *sptr = std::forward<T>(right);
174+ *wptr = *sptr;
175+ return *this;
176+ }
177+
178+ class weak {
179+ std::shared_ptr<boxed::weak> wptr;
180+ public:
181+ weak(const ref& r) : wptr(r.wptr) {}
182+
183+ operator boxed() const {
184+ return *wptr;
185+ }
186+
187+ auto operator()() const -> boxed {
188+ return static_cast<boxed>(*wptr)();
189+ }
190+
191+ auto operator()(const boxed& arg) const -> boxed {
192+ return static_cast<boxed>(*wptr)(arg);
193+ }
194+ }; // class ref::weak
195+ }; // class boxed::ref
135
196
136 }; // class boxed
197 }; // class boxed
137
198
@@ -166,60 +227,6 @@ namespace purescript {
166 return value;
227 return value;
167 }
228 }
168
229
169− class boxed_r {
170− friend class boxed_weak_r;
171− std::shared_ptr<boxed> ptr;
172− std::shared_ptr<boxed::weak> wptr;
173−
174− public:
175− boxed_r() : ptr(std::make_shared<boxed>())
176− , wptr(std::make_shared<boxed::weak>(*ptr)) {}
177−
178− operator const boxed&() const {
179− return *ptr;
180− }
181−
182− operator boxed&() {
183− return *ptr;
184− }
185−
186− auto operator()() const -> boxed {
187− return (*ptr)();
188− }
189−
190− auto operator()(const boxed& arg) const -> boxed {
191− return (*ptr)(arg);
192− }
193−
194− template <typename T>
195− auto operator=(T&& right) -> boxed_r& {
196− *ptr = std::forward<T>(right);
197− *wptr = *ptr;
198− return *this;
199− }
200−
201− }; // class boxed_r
202−
203− class boxed_weak_r {
204− std::shared_ptr<boxed::weak> wptr;
205−
206− public:
207− boxed_weak_r(const boxed_r& r) : wptr(r.wptr) {}
208−
209− operator boxed() const {
210− return *wptr;
211− }
212−
213− auto operator()() const -> boxed {
214− return static_cast<boxed>(*wptr)();
215− }
216−
217− auto operator()(const boxed& arg) const -> boxed {
218− return static_cast<boxed>(*wptr)(arg);
219− }
220−
221− }; // class boxed_weak_r
222−
223 inline auto array_length(const boxed& a) -> boxed::array_t::size_type {
230 inline auto array_length(const boxed& a) -> boxed::array_t::size_type {
224 return unbox<boxed::array_t>(a).size();
231 return unbox<boxed::array_t>(a).size();
225 }
232 }
src/CodeGen/Cpp.hs+2−2
@@ -255,10 +255,10 @@ moduleToCpp (Module _ coms mn _ imps _ foreigns decls) _ =
255 bindersToCpp ss binders vals
255 bindersToCpp ss binders vals
256 valueToCpp (Let _ ds val) = do
256 valueToCpp (Let _ ds val) = do
257 let recurs = concatMap getNames $ filter isRec ds
257 let recurs = concatMap getNames $ filter isRec ds
258− recurDs = (\v -> AST.Var Nothing $ "boxed_r " <> identToCpp v) <$> recurs
258+ recurDs = (\v -> AST.Var Nothing $ "boxed::ref " <> identToCpp v) <$> recurs
259 recurDsWeak = (\v -> AST.Var
259 recurDsWeak = (\v -> AST.Var
260 Nothing
260 Nothing
261− ("boxed_weak_r " <> identToCpp v <> unretainedSuffix <> "(" <> identToCpp v <> ")")
261+ ("boxed::ref::weak " <> identToCpp v <> unretainedSuffix <> "(" <> identToCpp v <> ")")
262 ) <$> recurs
262 ) <$> recurs
263 mutualRecurWarning = if any isMutRec $ filter isRec ds
263 mutualRecurWarning = if any isMutRec $ filter isRec ds
264 then [AST.Var Nothing "#pragma message(\"Mutually recursive lets will cause retain cycles (memory leaks)\") //"]
264 then [AST.Var Nothing "#pragma message(\"Mutually recursive lets will cause retain cycles (memory leaks)\") //"]