… | |
… | |
23 | */ |
23 | */ |
24 | |
24 | |
25 | #include <string> |
25 | #include <string> |
26 | #include <sstream> |
26 | #include <sstream> |
27 | #include <map> |
27 | #include <map> |
|
|
28 | #include <set> |
28 | #include <vector> |
29 | #include <vector> |
29 | |
30 | |
30 | #include <inttypes.h> |
31 | #include <inttypes.h> |
31 | |
32 | |
32 | namespace cpjit |
33 | namespace cpjit |
33 | { |
34 | { |
34 | |
35 | |
35 | #define CPJIT_MAX_ARGS «$max_args» |
36 | #define CPJIT_MAX_ARGS «$max_args» |
36 | #define CPJIT_NULLID "" |
37 | #define CPJIT_NULLID "" |
37 | |
|
|
38 | // environment for persistent or temporary storage |
|
|
39 | struct env |
|
|
40 | { |
|
|
41 | std::string path, idxpath; |
|
|
42 | bool temporary; |
|
|
43 | int idxfd; |
|
|
44 | long idxstamp; |
|
|
45 | int nextid; |
|
|
46 | |
|
|
47 | void dolock (bool lock); |
|
|
48 | void lock (); |
|
|
49 | void unlock (); |
|
|
50 | |
|
|
51 | bool load_index (); |
|
|
52 | void save_index (); |
|
|
53 | |
|
|
54 | std::map<std::string, std::string> id2file; // id to object/sofile mapping (or empty) |
|
|
55 | std::map<std::string, void *> file2so; // file to loaded so handle |
|
|
56 | std::vector< std::pair<std::string, std::string> > fragments; // not-yet-compiled sources |
|
|
57 | |
|
|
58 | void register_fragment (const std::string &id, const std::string &source); |
|
|
59 | void *dlsym (const std::string &id, const char *symbol); |
|
|
60 | void *sym (const std::string &id, const char *symbol); |
|
|
61 | |
|
|
62 | public: |
|
|
63 | env (const std::string &path = CPJIT_NULLID, bool temporary = false); |
|
|
64 | ~env (); |
|
|
65 | |
|
|
66 | // compact all fragments && invalidate ALL pointers |
|
|
67 | void compact (); |
|
|
68 | // completely delete the environment on disk |
|
|
69 | void clear (); |
|
|
70 | }; |
|
|
71 | |
|
|
72 | struct fun |
|
|
73 | { |
|
|
74 | env &e; |
|
|
75 | std::string id; |
|
|
76 | void *funptr; |
|
|
77 | |
|
|
78 | fun (env &e, const std::string &id, const std::string &source); |
|
|
79 | |
|
|
80 | // is compiled function available? |
|
|
81 | bool compiled () |
|
|
82 | { |
|
|
83 | return funptr; |
|
|
84 | } |
|
|
85 | |
|
|
86 | // returns the function pointer |
|
|
87 | void *ptr (); |
|
|
88 | }; |
|
|
89 | |
|
|
90 | struct funbuild : std::ostringstream |
|
|
91 | { |
|
|
92 | env &e; |
|
|
93 | std::string retlist, arglist; |
|
|
94 | |
|
|
95 | funbuild (env &e, const char *rettype, ...); |
|
|
96 | void finish (std::string &id, std::string &source); |
|
|
97 | }; |
|
|
98 | |
38 | |
99 | typedef unsigned char U8; |
39 | typedef unsigned char U8; |
100 | typedef signed char I8; |
40 | typedef signed char I8; |
101 | typedef uint16_t U16; |
41 | typedef uint16_t U16; |
102 | typedef int16_t I16; |
42 | typedef int16_t I16; |
… | |
… | |
130 | template<> struct typestr<I32 *> { static const char str[]; }; |
70 | template<> struct typestr<I32 *> { static const char str[]; }; |
131 | template<> struct typestr<I64 *> { static const char str[]; }; |
71 | template<> struct typestr<I64 *> { static const char str[]; }; |
132 | template<> struct typestr<FLT *> { static const char str[]; }; |
72 | template<> struct typestr<FLT *> { static const char str[]; }; |
133 | template<> struct typestr<DBL *> { static const char str[]; }; |
73 | template<> struct typestr<DBL *> { static const char str[]; }; |
134 | |
74 | |
135 | «repeat» |
75 | typedef std::string funid; |
136 | template<typename R«, typename A$_|»> |
76 | |
137 | struct fun«$_» : fun |
77 | // the source of a function |
|
|
78 | struct funsrc { |
|
|
79 | funid id; // the unique id (md5 of source) |
|
|
80 | |
|
|
81 | std::set<std::string> hdrlist; // any unique headers |
|
|
82 | |
|
|
83 | std::string retlist; // the return type |
|
|
84 | std::string arglist; // the argument declaration |
|
|
85 | std::string body; // the function body |
|
|
86 | |
|
|
87 | funsrc (); |
|
|
88 | void update_id (const char *pfx); |
|
|
89 | }; |
|
|
90 | |
|
|
91 | struct fun |
138 | { |
92 | { |
139 | fun«$_» (env &e, const std::string &id, const std::string &source) |
93 | struct env &e; |
140 | : fun(e, id, source) |
94 | funid id; |
|
|
95 | |
|
|
96 | void *funptr; |
|
|
97 | |
|
|
98 | fun (env &e, const funid &id); |
|
|
99 | |
|
|
100 | // is compiled function available? |
|
|
101 | bool compiled () |
141 | { |
102 | { |
|
|
103 | return funptr; |
142 | } |
104 | } |
143 | |
105 | |
144 | int operator ()(«A$_ a$_|, ») |
106 | // returns the function pointer |
|
|
107 | void *ptr (); |
|
|
108 | |
|
|
109 | «repeat» |
|
|
110 | template<typename R«, typename A$_|»> |
|
|
111 | R call («A$_ a$_|, ») |
145 | { |
112 | { |
146 | return ((R (*)(«A$_|, »)) ptr ())(«a$_|, »); |
113 | return ((R (*)(«A$_|, »)) ptr ())(«a$_|, »); |
147 | } |
114 | } |
|
|
115 | «end» |
|
|
116 | |
|
|
117 | «repeat» |
|
|
118 | template<typename R«, typename A$_|»> |
|
|
119 | R operator ()(«A$_ a$_|, ») |
|
|
120 | { |
|
|
121 | call<R«, A$_|»> («a$_|, »); |
|
|
122 | } |
|
|
123 | «end» |
148 | }; |
124 | }; |
149 | «end» |
125 | |
|
|
126 | // environment for persistent or temporary storage |
|
|
127 | struct env |
|
|
128 | { |
|
|
129 | std::string path, idxpath; |
|
|
130 | bool temporary; |
|
|
131 | int idxfd; |
|
|
132 | long idxstamp; |
|
|
133 | int nextid; |
|
|
134 | |
|
|
135 | void dolock (bool lock); |
|
|
136 | void lock (); |
|
|
137 | void unlock (); |
|
|
138 | |
|
|
139 | bool load_index (); |
|
|
140 | void save_index (); |
|
|
141 | |
|
|
142 | std::map<funid, std::string> id2file; // id to object/sofile mapping (or empty) |
|
|
143 | std::map<std::string, void *> file2so; // file to loaded so handle |
|
|
144 | std::vector<funsrc> fragments; // not-yet-compiled sources |
|
|
145 | // std::set<fun> funs; // should go away |
|
|
146 | |
|
|
147 | void register_fragment (const funsrc &frag); |
|
|
148 | void *dlsym (const std::string &id, const char *symbol); |
|
|
149 | void *sym (const std::string &id, const char *symbol); |
|
|
150 | |
|
|
151 | public: |
|
|
152 | env (const std::string &path = CPJIT_NULLID, bool temporary = false); |
|
|
153 | ~env (); |
|
|
154 | |
|
|
155 | struct fun *get (funid id); |
|
|
156 | |
|
|
157 | // compact all fragments && invalidate ALL pointers |
|
|
158 | void compact (); |
|
|
159 | // completely delete the environment on disk |
|
|
160 | void clear (); |
|
|
161 | }; |
|
|
162 | |
|
|
163 | struct funbuild : funsrc |
|
|
164 | { |
|
|
165 | std::ostringstream bodystream; |
|
|
166 | env &e; |
|
|
167 | |
|
|
168 | funbuild (env &e, const char *rettype, ...); |
|
|
169 | |
|
|
170 | void header (const std::string &hdr); |
|
|
171 | |
|
|
172 | funbuild &operator <<(const char *src); |
|
|
173 | funbuild &operator <<(const std::string &src); |
|
|
174 | |
|
|
175 | fun *get (); |
|
|
176 | }; |
150 | |
177 | |
151 | «repeat» |
178 | «repeat» |
152 | template<typename R«, typename A$_|»> |
179 | template<typename R«, typename A$_|»> |
153 | struct funbuild«$_» : funbuild |
180 | struct funbuild«$_» : funbuild |
154 | { |
181 | { |
155 | funbuild«$_» (env &e) |
182 | funbuild«$_» (env &e) |
156 | : funbuild(e, typestr<R>::str«, typestr<A$_>::str|», (const char *)0) |
183 | : funbuild(e, typestr<R>::str«, typestr<A$_>::str|», (const char *)0) |
157 | { |
184 | { |
158 | } |
185 | } |
159 | |
|
|
160 | fun«$_»<R«, A$_|»> *get () |
|
|
161 | { |
|
|
162 | std::string id, source; |
|
|
163 | finish (id, source); |
|
|
164 | return new fun«$_»<R«, A$_|»> (e, id, source); |
|
|
165 | } |
|
|
166 | }; |
186 | }; |
167 | «end» |
187 | «end» |
168 | |
188 | |
169 | } |
189 | } |
170 | |
190 | |