git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Clean up structure of runtime classes
commit9eb0b938927c13b36b4f970fdb5546380560e597 authorAndy Arvanitis <andyarvanitis@gmail.com> dateFri 25 Jan 2019, 19:47 (8 years ago) parent21477b3
2 files changed+96−89
runtime/purescript.h+94−87 src/CodeGen/Cpp.hs+2−2
runtime/purescript.h+94−87
@@ -27,8 +27,8 @@ namespace purescript {
2727
2828 using std::string;
2929
30− class boxed : public std::shared_ptr<void> {
31−
30+ class boxed {
31+ std::shared_ptr<void> shared;
3232 public:
3333 using fn_t = std::function<boxed(const boxed&)>;
3434 using eff_fn_t = std::function<boxed(void)>;
@@ -36,102 +36,163 @@ namespace purescript {
3636 using array_t = std::deque<boxed>;
3737
3838 public:
39− using std::shared_ptr<void>::shared_ptr;
39+ boxed() noexcept : shared() {}
40+ boxed(const std::nullptr_t) noexcept : shared() {}
4041
41− boxed() noexcept : std::shared_ptr<void>() {}
42− boxed(const std::nullptr_t) noexcept : std::shared_ptr<void>() {}
43− boxed(const std::shared_ptr<void>& p) : std::shared_ptr<void>::shared_ptr(p) {}
44− boxed(const int n) : std::shared_ptr<void>(std::make_shared<int>(n)) {}
45− boxed(const long n) : std::shared_ptr<void>(std::make_shared<int>(static_cast<int>(n))) {
42+ template <typename T>
43+ boxed(std::shared_ptr<T>&& other) : shared(std::move(other)) {}
44+
45+ template <typename T>
46+ boxed(const std::shared_ptr<T>& other) : shared(other) {}
47+
48+ boxed(const int n) : shared(std::make_shared<int>(n)) {}
49+
50+ boxed(const long n) : shared(std::make_shared<int>(static_cast<int>(n))) {
4651#if !defined(NDEBUG) // if debug build
4752 if (n < std::numeric_limits<int>::min() || n > std::numeric_limits<int>::max()) {
4853 throw std::runtime_error("integer out of range");
4954 }
5055#endif // !defined(NDEBUG)
5156 }
52− boxed(const unsigned long n) : std::shared_ptr<void>(std::make_shared<int>(static_cast<int>(n))) {
57+
58+ boxed(const unsigned long n) : shared(std::make_shared<int>(static_cast<int>(n))) {
5359#if !defined(NDEBUG) // if debug build
5460 if (n > std::numeric_limits<int>::max()) {
5561 throw std::runtime_error("integer out of range");
5662 }
5763#endif // !defined(NDEBUG)
5864 }
59− boxed(const double n) : std::shared_ptr<void>(std::make_shared<double>(n)) {}
60− boxed(const bool b) : std::shared_ptr<void>(std::make_shared<bool>(b)) {}
61− boxed(const char s[]) : std::shared_ptr<void>(std::make_shared<string>(s)) {}
62− boxed(string&& s) : std::shared_ptr<void>(std::make_shared<string>(std::move(s))) {}
63− boxed(const string& s) : std::shared_ptr<void>(std::make_shared<string>(s)) {}
64− boxed(array_t&& l) : std::shared_ptr<void>(std::make_shared<array_t>(std::move(l))) {}
65− boxed(const array_t& l) : std::shared_ptr<void>(std::make_shared<array_t>(l)) {}
66− boxed(dict_t&& m) : std::shared_ptr<void>(std::make_shared<dict_t>(std::move(m))) {}
67− boxed(const dict_t& m) : std::shared_ptr<void>(std::make_shared<dict_t>(m)) {}
65+
66+ boxed(const double n) : shared(std::make_shared<double>(n)) {}
67+ boxed(const bool b) : shared(std::make_shared<bool>(b)) {}
68+ boxed(const char s[]) : shared(std::make_shared<string>(s)) {}
69+ boxed(string&& s) : shared(std::make_shared<string>(std::move(s))) {}
70+ boxed(const string& s) : shared(std::make_shared<string>(s)) {}
71+ boxed(array_t&& l) : shared(std::make_shared<array_t>(std::move(l))) {}
72+ boxed(const array_t& l) : shared(std::make_shared<array_t>(l)) {}
73+ boxed(dict_t&& m) : shared(std::make_shared<dict_t>(std::move(m))) {}
74+ boxed(const dict_t& m) : shared(std::make_shared<dict_t>(m)) {}
6875
6976 template <typename T,
7077 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
7178 boxed(const T& f,
7279 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)) {
7481 }
7582
7683 template <typename T,
7784 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
7885 boxed(const T& f,
7986 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();
8192 }
8293
8394 auto operator()(const boxed& arg) const -> boxed {
84− auto& f = *static_cast<fn_t*>(get());
95+ auto& f = *static_cast<fn_t*>(shared.get());
8596 return f(arg);
8697 }
8798
8899 auto operator()() const -> boxed {
89− auto& f = *static_cast<eff_fn_t*>(get());
100+ auto& f = *static_cast<eff_fn_t*>(shared.get());
90101 return f();
91102 }
92103
93104 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];
95106 }
96107
97108 auto operator[](const char key[]) -> boxed& {
98− return (*static_cast<dict_t*>(get()))[key];
109+ return (*static_cast<dict_t*>(shared.get()))[key];
99110 }
100111
101112#if !defined(NDEBUG) // if debug build
102113 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);
104115 }
105116
106117 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);
108119 }
109120#else // not debug build
110121 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];
112123 }
113124
114125 auto operator[](const int index) -> boxed& {
115− return (*static_cast<array_t*>(get()))[index];
126+ return (*static_cast<array_t*>(shared.get()))[index];
116127 }
117128#endif // !defined(NDEBUG)
118129
119130 class weak {
120− std::weak_ptr<void> ptr;
131+ std::weak_ptr<void> wptr;
121132
122133 public:
123134 weak() = delete;
124− weak(boxed& b) : ptr(b) {}
135+ weak(boxed& b) : wptr(b.shared) {}
125136
126137 operator boxed() const {
127138#if defined(NDEBUG)
128− return ptr.lock();
139+ return wptr.lock();
129140#else
130− return static_cast<std::shared_ptr<void>>(ptr);
141+ return static_cast<std::shared_ptr<void>>(wptr);
131142#endif
132143 }
133144
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
135196
136197 }; // class boxed
137198
@@ -166,60 +227,6 @@ namespace purescript {
166227 return value;
167228 }
168229
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−
223230 inline auto array_length(const boxed& a) -> boxed::array_t::size_type {
224231 return unbox<boxed::array_t>(a).size();
225232 }
src/CodeGen/Cpp.hs+2−2
@@ -255,10 +255,10 @@ moduleToCpp (Module _ coms mn _ imps _ foreigns decls) _ =
255255 bindersToCpp ss binders vals
256256 valueToCpp (Let _ ds val) = do
257257 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
259259 recurDsWeak = (\v -> AST.Var
260260 Nothing
261− ("boxed_weak_r " <> identToCpp v <> unretainedSuffix <> "(" <> identToCpp v <> ")")
261+ ("boxed::ref::weak " <> identToCpp v <> unretainedSuffix <> "(" <> identToCpp v <> ")")
262262 ) <$> recurs
263263 mutualRecurWarning = if any isMutRec $ filter isRec ds
264264 then [AST.Var Nothing "#pragma message(\"Mutually recursive lets will cause retain cycles (memory leaks)\") //"]