ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/libcpjit/cpjit.C
(Generate patch)

Comparing cvsroot/libcpjit/cpjit.C (file contents):
Revision 1.4 by root, Fri Oct 14 00:21:57 2005 UTC vs.
Revision 1.5 by root, Fri Oct 14 01:29:45 2005 UTC

74const char typestr<I32 *>::str[] = STR(TYPE_INT32) " *"; 74const char typestr<I32 *>::str[] = STR(TYPE_INT32) " *";
75const char typestr<I64 *>::str[] = STR(TYPE_INT64) " *"; 75const char typestr<I64 *>::str[] = STR(TYPE_INT64) " *";
76const char typestr<FLT *>::str[] = "float" " *"; 76const char typestr<FLT *>::str[] = "float" " *";
77const char typestr<DBL *>::str[] = "double" " *"; 77const char typestr<DBL *>::str[] = "double" " *";
78 78
79struct digest 79struct digest : md5_ctx
80{ 80{
81 unsigned char data[16]; 81 digest ();
82 82 void operator ()(const std::string &data);
83 digest (const std::string &str);
84 operator std::string(); 83 operator std::string();
85}; 84};
86 85
87digest::digest (const std::string &str) 86digest::digest ()
88{ 87{
89 MD5_CTX ctx; 88 md5_init_ctx (this);
90 MD5Init (&ctx); 89}
91 MD5Update (&ctx, (const unsigned char *)str.c_str (), str.size ());
92 MD5Final (&ctx);
93 90
94 memcpy (data, ctx.digest, sizeof (data)); 91void digest::operator ()(const std::string &data)
92{
93 md5_process_bytes (data.c_str (), data.size (), this);
95} 94}
96 95
97digest::operator std::string () 96digest::operator std::string ()
98{ 97{
98 unsigned char data[16];
99 std::ostringstream s; 99 std::ostringstream s;
100 100
101 md5_finish_ctx (this, data);
102
101 for (int i = 0; i < 15; i++) 103 for (int i = 0; i < 16; i++)
102 s << std::setfill ('0') << std::hex << std::setw (2) << (int)data [i]; 104 s << std::setfill ('0') << std::hex << std::setw (2) << (int)data [i];
103 105
104 return s.str (); 106 return s.str ();
105} 107}
106 108
143 FATAL (path << ": unable to open index file" << index); 145 FATAL (path << ": unable to open index file" << index);
144 146
145 lock (); 147 lock ();
146 load_index (); 148 load_index ();
147 unlock (); 149 unlock ();
148
149 nextid = 0;
150} 150}
151 151
152env::~env () 152env::~env ()
153{ 153{
154 if (temporary) 154 if (temporary)
155 clear ();
156}
157
158void env::clear ()
159{
160 DIR *dir = opendir (path.c_str ());
161
162 if (dir)
155 { 163 {
156 DIR *dir = opendir (path.c_str ()); 164 struct dirent *de;
157 165 while ((de = readdir (dir)))
158 if (dir)
159 { 166 {
160 struct dirent *de;
161 while ((de = readdir (dir)))
162 {
163 if (de->d_name [0] == '.') 167 if (de->d_name [0] == '.')
164 continue; 168 continue;
165 169
166 std::string f = path + "/" + de->d_name; 170 std::string f = path + "/" + de->d_name;
167 unlink (f.c_str ()); 171 unlink (f.c_str ());
168 }
169
170 closedir (dir);
171 } 172 }
172 173
173 if (rmdir (path.c_str ())) 174 closedir (dir);
174 FATAL (path << ": unable to remove libcpjit temporary directory" << ERRNO);
175 } 175 }
176
177 if (rmdir (path.c_str ()))
178 FATAL (path << ": unable to remove libcpjit directory" << ERRNO);
176} 179}
177 180
178void env::dolock (bool lock) 181void env::dolock (bool lock)
179{ 182{
180 struct flock fl; 183 struct flock fl;
205 std::ifstream f ((this->path + "/libcpjit.idx").c_str ()); 208 std::ifstream f ((this->path + "/libcpjit.idx").c_str ());
206 assert (("not a cpjit directory", f)); 209 assert (("not a cpjit directory", f));
207 f.close (); 210 f.close ();
208} 211}
209 212
210std::string 213void
211env::genid () 214env::save_index ()
212{ 215{
213 std::ostringstream os; 216 std::ifstream f ((this->path + "/libcpjit.idx").c_str ());
214 217 assert (("not a cpjit directory", f));
215 os << "i" << ++nextid; 218 f.close ();
216 return os.str ();
217} 219}
218 220
219fun::fun (env &e, const idstr &id) 221fun::fun (env &e, const std::string &id, const std::string &source)
220: e(e), id(id), funptr(0) 222: e(e), id(id), source(source), funptr(0)
221{ 223{
222}
223
224void fun::set_source (const std::string source)
225{
226 this->source = source;
227} 224}
228 225
229void *fun::ptr () 226void *fun::ptr ()
230{ 227{
231 if (!funptr) 228 if (!funptr)
232 { 229 {
233 std::string base = e.path + "/" + (std::string) digest (source); 230 e.lock ();
231 e.load_index ();
232
233 std::string base = e.path + "/" + id;
234 234
235 std::string fc = base + ".c"; 235 std::string fc = base + ".c";
236 std::string fo = base + ".o"; 236 std::string fo = base + ".o";
237 std::string fso = base + ".so"; 237 std::string fso = base + ".so";
238 std::string fa = base + ".a"; 238 std::string fa = base + ".a";
246 unlink (fc.c_str ()); 246 unlink (fc.c_str ());
247 247
248 system (("gcc -O6 -nostdlib -lgcc -shared -o " + fso + " " + fo).c_str ()); 248 system (("gcc -O6 -nostdlib -lgcc -shared -o " + fso + " " + fo).c_str ());
249 249
250 printf ("%s\n", fso.c_str ()); 250 printf ("%s\n", fso.c_str ());
251 sleep (10);
252 251
253 void *so = dlopen (fso.c_str (), RTLD_LAZY); 252 void *so = dlopen (fso.c_str (), RTLD_LAZY);
254 assert (so); 253 assert (so);
255 254
256 funptr = dlsym (so, id.c_str ()); 255 funptr = dlsym (so, id.c_str ());
257 assert (funptr); 256 assert (funptr);
257
258 e.save_index ();
259 e.unlock ();
258 } 260 }
259 261
260 return funptr; 262 return funptr;
261} 263}
262 264
263funbuild::funbuild (env &e, const idstr &id, const char *rettype, ...) 265funbuild::funbuild (env &e, const char *rettype, ...)
264: e(e), id(id) 266: e(e)
265{ 267{
268 retlist = rettype;
269
266 std::ostringstream hdrs; 270 std::ostringstream argl;
267
268 if (is_null (id))
269 this->id = e.genid ();
270
271 hdrs << rettype << " " << this->id << "(";
272 271
273 va_list ap; 272 va_list ap;
274 va_start (ap, rettype); 273 va_start (ap, rettype);
275 274
276 int args = 0; 275 int args = 0;
277 while ((rettype = va_arg (ap, const char *))) 276 while ((rettype = va_arg (ap, const char *)))
278 { 277 {
279 if (args++) 278 if (args++)
280 hdrs << ", "; 279 argl << ", ";
281 280
282 hdrs << rettype << " a" << args; 281 argl << rettype << " a" << args;
283 } 282 }
284 283
285 va_end (ap); 284 va_end (ap);
286 285
287 hdrs << ")\n{\n"; 286 arglist = argl.str ();
288
289 hdr = hdrs.str ();
290} 287}
291 288
292std::string 289void
293funbuild::finish () 290funbuild::finish (std::string &id, std::string &source)
294{ 291{
295 *this << "\n}\n"; 292 digest dgst;
296 293
297 return hdr + str (); 294 dgst (retlist);
298} 295 dgst (arglist);
296 dgst (str ());
299 297
298 id = "f_" + (std::string) dgst;
299
300 std::ostringstream o;
301 o << retlist << " " << id << " (" << arglist << ")\n{\n" << str () << "\n}\n";
302 source = o.str ();
300} 303}
304
305}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines