ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/libcpjit/cpjit.C
Revision: 1.3
Committed: Wed Oct 12 19:24:24 2005 UTC (18 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.2: +16 -5 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 /*
2     cpjit.C -- c portable jit in time compiler
3     Copyright (C) 2005 Marc Lehmann <cpjit@schmorp.de>
4    
5     This file is part of libcpjit.
6    
7     libcpjit is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but 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.
16    
17     You should have received a copy of the GNU General Public License
18     along with gvpe; if not, write to the Free Software
19     Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20     */
21    
22     #include "config.h"
23    
24     #include "cpjit.h"
25    
26 root 1.2 #include <cassert>
27     #include <cstdlib>
28 root 1.1 #include <cstdarg>
29 root 1.2 #include <cstdio>
30 root 1.1 #include <sstream>
31 root 1.2 #include <fstream>
32    
33     #include <sys/stat.h>
34     #include <sys/types.h>
35     #include <dirent.h>
36    
37     #include <dlfcn.h>
38 root 1.1
39     #define STR_(str) #str
40     #define STR(str) STR_(str)
41    
42     namespace cpjit
43     {
44    
45     const char typestr<U8 >::str[] = "unsigned " STR(TYPE_INT8);
46     const char typestr<U16 >::str[] = "unsigned " STR(TYPE_INT16);
47     const char typestr<U32 >::str[] = "unsigned " STR(TYPE_INT32);
48     const char typestr<U64 >::str[] = "unsigned " STR(TYPE_INT64);
49 root 1.2 const char typestr<I8 >::str[] = "signed " STR(TYPE_INT8);
50     const char typestr<I16 >::str[] = STR(TYPE_INT16);
51     const char typestr<I32 >::str[] = STR(TYPE_INT32);
52     const char typestr<I64 >::str[] = STR(TYPE_INT64);
53 root 1.1 const char typestr<F32 >::str[] = "float";
54     const char typestr<F64 >::str[] = "double";
55    
56 root 1.2 const char typestr<PTR >::str[] = "void" " *";
57    
58 root 1.1 const char typestr<U8 *>::str[] = "unsigned " STR(TYPE_INT8) " *";
59     const char typestr<U16 *>::str[] = "unsigned " STR(TYPE_INT16) " *";
60     const char typestr<U32 *>::str[] = "unsigned " STR(TYPE_INT32) " *";
61     const char typestr<U64 *>::str[] = "unsigned " STR(TYPE_INT64) " *";
62 root 1.2 const char typestr<I8 *>::str[] = "signed " STR(TYPE_INT8) " *";
63     const char typestr<I16 *>::str[] = STR(TYPE_INT16) " *";
64     const char typestr<I32 *>::str[] = STR(TYPE_INT32) " *";
65     const char typestr<I64 *>::str[] = STR(TYPE_INT64) " *";
66 root 1.1 const char typestr<F32 *>::str[] = "float" " *";
67     const char typestr<F64 *>::str[] = "double" " *";
68    
69 root 1.2 static inline bool
70     is_null (const std::string &s)
71     {
72     return s.empty ();
73     }
74    
75     env::env (const std::string &path, bool temporary)
76     : path(path), temporary(temporary)
77     {
78     if (is_null (path))
79     {
80     this->path = tmpnam (0);
81    
82     if (mkdir (this->path.c_str (), 0777))
83     {
84     perror ("libcpjit temporary directory");
85     exit (1);
86     }
87    
88     std::ofstream f ((this->path + "/libcpjit").c_str ());
89    
90     temporary = true;
91     }
92    
93     std::ifstream f ((this->path + "/libcpjit").c_str ());
94     assert (("not a cpjit directory", f));
95     f.close ();
96    
97     if (temporary)
98     nextid = 0;
99     else
100     abort (); // fetch from database
101     }
102    
103     env::~env ()
104     {
105     if (temporary)
106     {
107     DIR *dir = opendir (path.c_str ());
108    
109     if (dir)
110     {
111     struct dirent *de;
112     while ((de = readdir (dir)))
113     {
114     if (de->d_name [0] == '.')
115     continue;
116    
117     std::string f = path + "/" + de->d_name;
118     unlink (f.c_str ());
119     }
120    
121     closedir (dir);
122     }
123    
124     if (rmdir (path.c_str ()))
125     perror ("unable to remove libcpjit temporary directory");
126     }
127     }
128    
129     std::string
130     env::genid ()
131     {
132     std::ostringstream os;
133    
134     os << "i" << ++nextid;
135     return os.str ();
136     }
137    
138 root 1.1 fun::fun (env &e, const idstr &id)
139 root 1.2 : e(e), id(id), funptr(0)
140     {
141     }
142    
143 root 1.3 void fun::set_source (const std::string source)
144     {
145     this->source = source;
146     }
147    
148 root 1.2 void *fun::ptr ()
149 root 1.1 {
150 root 1.2 if (!funptr)
151     {
152     std::string fc = e.path + "/x.c";
153     std::string fo = e.path + "/x.o";
154     std::string fso = e.path + "/x.so";
155    
156     std::ofstream f (fc.c_str ());
157     f << source;
158     f.close ();
159    
160     system (("gcc -O6 -c -o " + fo + " " + fc).c_str ());
161    
162     unlink (fc.c_str ());
163    
164     system (("gcc -O6 -nostdlib -lgcc -shared -o " + fso + " " + fo).c_str ());
165    
166     void *so = dlopen (fso.c_str (), RTLD_LAZY);
167     assert (so);
168    
169     funptr = dlsym (so, id.c_str ());
170     assert (funptr);
171     }
172    
173     return funptr;
174 root 1.1 }
175    
176     funbuild::funbuild (env &e, const idstr &id, const char *rettype, ...)
177     : e(e), id(id)
178     {
179 root 1.3 std::ostringstream hdrs;
180    
181 root 1.2 if (is_null (id))
182     this->id = e.genid ();
183    
184 root 1.3 hdrs << rettype << " " << this->id << "(";
185 root 1.1
186     va_list ap;
187     va_start (ap, rettype);
188    
189     int args = 0;
190     while ((rettype = va_arg (ap, const char *)))
191     {
192     if (args++)
193 root 1.3 hdrs << ", ";
194 root 1.1
195 root 1.3 hdrs << rettype << " a" << args;
196 root 1.1 }
197    
198     va_end (ap);
199    
200 root 1.3 hdrs << ")\n{\n";
201    
202     hdr = hdrs.str ();
203 root 1.1 }
204    
205 root 1.3 std::string
206 root 1.1 funbuild::finish ()
207     {
208     *this << "\n}\n";
209 root 1.3
210     return hdr + str ();
211 root 1.1 }
212    
213     }