]>
Commit | Line | Data |
---|---|---|
b3378a02 | 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime |
c15969fd | 2 | * Copyright (C) 2009-2013 Jay Freeman (saurik) |
4644480a JF |
3 | */ |
4 | ||
c15969fd | 5 | /* GNU General Public License, Version 3 {{{ */ |
4644480a | 6 | /* |
c15969fd JF |
7 | * Cycript is free software: you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published | |
9 | * by the Free Software Foundation, either version 3 of the License, | |
10 | * or (at your option) any later version. | |
4644480a | 11 | * |
c15969fd JF |
12 | * Cycript is distributed in the hope that it will be useful, but |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
4644480a | 16 | * |
c15969fd | 17 | * You should have received a copy of the GNU General Public License |
b3378a02 JF |
18 | * along with Cycript. If not, see <http://www.gnu.org/licenses/>. |
19 | **/ | |
4644480a JF |
20 | /* }}} */ |
21 | ||
c5fa2867 JF |
22 | #ifndef CYCRIPT_POOLING_HPP |
23 | #define CYCRIPT_POOLING_HPP | |
5999c315 | 24 | |
b799113b JF |
25 | #include <cstdarg> |
26 | #include <cstdlib> | |
27 | ||
9185d5ef JF |
28 | #include <apr_pools.h> |
29 | #include <apr_strings.h> | |
5999c315 | 30 | |
37954781 | 31 | #include "Exception.hpp" |
2eb8215d | 32 | #include "Local.hpp" |
37954781 | 33 | #include "Standard.hpp" |
5999c315 | 34 | |
5999c315 JF |
35 | class CYPool { |
36 | private: | |
37 | apr_pool_t *pool_; | |
38 | ||
1560b2c8 JF |
39 | struct Cleaner { |
40 | Cleaner *next_; | |
41 | void (*code_)(void *); | |
42 | void *data_; | |
43 | ||
44 | Cleaner(Cleaner *next, void (*code)(void *), void *data) : | |
45 | next_(next), | |
46 | code_(code), | |
47 | data_(data) | |
48 | { | |
49 | } | |
50 | } *cleaner_; | |
5999c315 | 51 | |
1560b2c8 JF |
52 | public: |
53 | CYPool() : | |
54 | cleaner_(NULL) | |
b799113b | 55 | { |
1560b2c8 | 56 | _aprcall(apr_pool_create(&pool_, NULL)); |
b799113b JF |
57 | } |
58 | ||
5999c315 | 59 | ~CYPool() { |
1560b2c8 JF |
60 | for (Cleaner *cleaner(cleaner_); cleaner_ != NULL; cleaner_ = cleaner_->next_) |
61 | (*cleaner->code_)(cleaner->data_); | |
5999c315 JF |
62 | apr_pool_destroy(pool_); |
63 | } | |
64 | ||
b1ff2d78 JF |
65 | void Clear() { |
66 | apr_pool_clear(pool_); | |
67 | } | |
68 | ||
5999c315 JF |
69 | operator apr_pool_t *() const { |
70 | return pool_; | |
71 | } | |
72 | ||
b799113b JF |
73 | void *operator()(size_t size) const { |
74 | return apr_palloc(pool_, size); | |
75 | } | |
76 | ||
77 | char *strdup(const char *data) const { | |
5999c315 JF |
78 | return apr_pstrdup(pool_, data); |
79 | } | |
80 | ||
b799113b | 81 | char *strndup(const char *data, size_t size) const { |
5999c315 JF |
82 | return apr_pstrndup(pool_, data, size); |
83 | } | |
b799113b JF |
84 | |
85 | char *strmemdup(const char *data, size_t size) const { | |
86 | return apr_pstrmemdup(pool_, data, size); | |
87 | } | |
88 | ||
89 | char *sprintf(const char *format, ...) const { | |
90 | va_list args; | |
91 | va_start(args, format); | |
92 | char *data(vsprintf(format, args)); | |
93 | va_end(args); | |
94 | return data; | |
95 | } | |
96 | ||
97 | char *vsprintf(const char *format, va_list args) const { | |
98 | return apr_pvsprintf(pool_, format, args); | |
99 | } | |
1560b2c8 JF |
100 | |
101 | void atexit(void (*code)(void *), void *data = NULL); | |
5999c315 JF |
102 | }; |
103 | ||
b799113b JF |
104 | _finline void *operator new(size_t size, CYPool &pool) { |
105 | return pool(size); | |
106 | } | |
107 | ||
108 | _finline void *operator new [](size_t size, CYPool &pool) { | |
109 | return pool(size); | |
110 | } | |
111 | ||
1560b2c8 JF |
112 | _finline void CYPool::atexit(void (*code)(void *), void *data) { |
113 | cleaner_ = new(*this) Cleaner(cleaner_, code, data); | |
114 | } | |
115 | ||
1ef7d061 | 116 | struct CYData { |
b799113b | 117 | CYPool *pool_; |
1850a470 JF |
118 | unsigned count_; |
119 | ||
120 | CYData() : | |
121 | count_(1) | |
122 | { | |
123 | } | |
1ef7d061 | 124 | |
b799113b JF |
125 | CYData(CYPool &pool) : |
126 | pool_(&pool), | |
127 | count_(_not(unsigned)) | |
128 | { | |
129 | } | |
130 | ||
1ef7d061 JF |
131 | virtual ~CYData() { |
132 | } | |
133 | ||
b799113b JF |
134 | static void *operator new(size_t size, CYPool &pool) { |
135 | void *data(pool(size)); | |
136 | reinterpret_cast<CYData *>(data)->pool_ = &pool; | |
1ef7d061 JF |
137 | return data; |
138 | } | |
139 | ||
140 | static void *operator new(size_t size) { | |
b799113b | 141 | return operator new(size, *new CYPool()); |
1ef7d061 JF |
142 | } |
143 | ||
144 | static void operator delete(void *data) { | |
b799113b | 145 | delete reinterpret_cast<CYData *>(data)->pool_; |
1ef7d061 | 146 | } |
1ef7d061 JF |
147 | }; |
148 | ||
a846a8cd JF |
149 | template <typename Type_> |
150 | struct CYPoolAllocator { | |
b799113b | 151 | CYPool *pool_; |
a846a8cd JF |
152 | |
153 | typedef Type_ value_type; | |
154 | typedef value_type *pointer; | |
155 | typedef const value_type *const_pointer; | |
156 | typedef value_type &reference; | |
157 | typedef const value_type &const_reference; | |
158 | typedef std::size_t size_type; | |
159 | typedef std::ptrdiff_t difference_type; | |
160 | ||
161 | CYPoolAllocator() : | |
162 | pool_(NULL) | |
163 | { | |
164 | } | |
165 | ||
166 | template <typename Right_> | |
167 | CYPoolAllocator(const CYPoolAllocator<Right_> &rhs) : | |
168 | pool_(rhs.pool_) | |
169 | { | |
170 | } | |
171 | ||
172 | pointer allocate(size_type size, const void *hint = 0) { | |
b799113b | 173 | return reinterpret_cast<pointer>((*pool_)(size)); |
a846a8cd JF |
174 | } |
175 | ||
176 | void deallocate(pointer data, size_type size) { | |
177 | } | |
178 | ||
179 | void construct(pointer address, const Type_ &rhs) { | |
180 | new(address) Type_(rhs); | |
181 | } | |
182 | ||
183 | void destroy(pointer address) { | |
184 | address->~Type_(); | |
185 | } | |
186 | ||
187 | template <typename Right_> | |
188 | inline bool operator==(const CYPoolAllocator<Right_> &rhs) { | |
189 | return pool_ == rhs.pool_; | |
190 | } | |
191 | ||
192 | template <typename Right_> | |
193 | inline bool operator!=(const CYPoolAllocator<Right_> &rhs) { | |
194 | return !operator==(rhs); | |
195 | } | |
196 | ||
197 | template <typename Right_> | |
198 | struct rebind { | |
199 | typedef CYPoolAllocator<Right_> other; | |
200 | }; | |
201 | }; | |
202 | ||
2eb8215d JF |
203 | class CYLocalPool : |
204 | public CYPool | |
205 | { | |
206 | private: | |
b799113b | 207 | CYLocal<CYPool> local_; |
2eb8215d JF |
208 | |
209 | public: | |
210 | CYLocalPool() : | |
211 | CYPool(), | |
b799113b | 212 | local_(this) |
2eb8215d JF |
213 | { |
214 | } | |
215 | }; | |
216 | ||
217 | #define $pool \ | |
b799113b | 218 | (*CYLocal<CYPool>::Get()) |
2eb8215d | 219 | |
c5fa2867 | 220 | #endif/*CYCRIPT_POOLING_HPP*/ |