diff options
author | Mike Pall <mike> | 2012-06-09 15:04:03 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2012-06-09 15:12:44 +0200 |
commit | 9a9509c66a98d0bf42003ad5d06e8f275c5ff1f5 (patch) | |
tree | f5ca35d9ed7cc66f644828233f511f6db4634849 /src/buildvm_lib.c | |
parent | 0a6c8338d240dd318db2f5269414dcf7ddc9ed35 (diff) | |
download | luajit-9a9509c66a98d0bf42003ad5d06e8f275c5ff1f5.tar.gz luajit-9a9509c66a98d0bf42003ad5d06e8f275c5ff1f5.tar.bz2 luajit-9a9509c66a98d0bf42003ad5d06e8f275c5ff1f5.zip |
Reorganize build process.
Drop pre-translated buildvm_*.h.
Rename buildvm_*.dasc to vm_*.dasc.
Move buildvm* to host directory.
Build minilua, unless HOST_LUA is set.
Use HOST_LUA to run DynASM.
Translate only vm_*.dasc for target architecture.
Diffstat (limited to 'src/buildvm_lib.c')
-rw-r--r-- | src/buildvm_lib.c | 377 |
1 files changed, 0 insertions, 377 deletions
diff --git a/src/buildvm_lib.c b/src/buildvm_lib.c deleted file mode 100644 index 3231d3ad..00000000 --- a/src/buildvm_lib.c +++ /dev/null | |||
@@ -1,377 +0,0 @@ | |||
1 | /* | ||
2 | ** LuaJIT VM builder: library definition compiler. | ||
3 | ** Copyright (C) 2005-2012 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #include "buildvm.h" | ||
7 | #include "lj_obj.h" | ||
8 | #include "lj_lib.h" | ||
9 | |||
10 | /* Context for library definitions. */ | ||
11 | static uint8_t obuf[8192]; | ||
12 | static uint8_t *optr; | ||
13 | static char modname[80]; | ||
14 | static size_t modnamelen; | ||
15 | static char funcname[80]; | ||
16 | static int modstate, regfunc; | ||
17 | static int ffid, recffid, ffasmfunc; | ||
18 | |||
19 | enum { | ||
20 | REGFUNC_OK, | ||
21 | REGFUNC_NOREG, | ||
22 | REGFUNC_NOREGUV | ||
23 | }; | ||
24 | |||
25 | static void libdef_name(const char *p, int kind) | ||
26 | { | ||
27 | size_t n = strlen(p); | ||
28 | if (kind != LIBINIT_STRING) { | ||
29 | if (n > modnamelen && p[modnamelen] == '_' && | ||
30 | !strncmp(p, modname, modnamelen)) { | ||
31 | p += modnamelen+1; | ||
32 | n -= modnamelen+1; | ||
33 | } | ||
34 | } | ||
35 | if (n > LIBINIT_MAXSTR) { | ||
36 | fprintf(stderr, "Error: string too long: '%s'\n", p); | ||
37 | exit(1); | ||
38 | } | ||
39 | if (optr+1+n+2 > obuf+sizeof(obuf)) { /* +2 for caller. */ | ||
40 | fprintf(stderr, "Error: output buffer overflow\n"); | ||
41 | exit(1); | ||
42 | } | ||
43 | *optr++ = (uint8_t)(n | kind); | ||
44 | memcpy(optr, p, n); | ||
45 | optr += n; | ||
46 | } | ||
47 | |||
48 | static void libdef_endmodule(BuildCtx *ctx) | ||
49 | { | ||
50 | if (modstate != 0) { | ||
51 | char line[80]; | ||
52 | const uint8_t *p; | ||
53 | int n; | ||
54 | if (modstate == 1) | ||
55 | fprintf(ctx->fp, " (lua_CFunction)0"); | ||
56 | fprintf(ctx->fp, "\n};\n"); | ||
57 | fprintf(ctx->fp, "static const uint8_t %s%s[] = {\n", | ||
58 | LABEL_PREFIX_LIBINIT, modname); | ||
59 | line[0] = '\0'; | ||
60 | for (n = 0, p = obuf; p < optr; p++) { | ||
61 | n += sprintf(line+n, "%d,", *p); | ||
62 | if (n >= 75) { | ||
63 | fprintf(ctx->fp, "%s\n", line); | ||
64 | n = 0; | ||
65 | line[0] = '\0'; | ||
66 | } | ||
67 | } | ||
68 | fprintf(ctx->fp, "%s%d\n};\n#endif\n\n", line, LIBINIT_END); | ||
69 | } | ||
70 | } | ||
71 | |||
72 | static void libdef_module(BuildCtx *ctx, char *p, int arg) | ||
73 | { | ||
74 | UNUSED(arg); | ||
75 | if (ctx->mode == BUILD_libdef) { | ||
76 | libdef_endmodule(ctx); | ||
77 | optr = obuf; | ||
78 | *optr++ = (uint8_t)ffid; | ||
79 | *optr++ = (uint8_t)ffasmfunc; | ||
80 | *optr++ = 0; /* Hash table size. */ | ||
81 | modstate = 1; | ||
82 | fprintf(ctx->fp, "#ifdef %sMODULE_%s\n", LIBDEF_PREFIX, p); | ||
83 | fprintf(ctx->fp, "#undef %sMODULE_%s\n", LIBDEF_PREFIX, p); | ||
84 | fprintf(ctx->fp, "static const lua_CFunction %s%s[] = {\n", | ||
85 | LABEL_PREFIX_LIBCF, p); | ||
86 | } | ||
87 | modnamelen = strlen(p); | ||
88 | if (modnamelen > sizeof(modname)-1) { | ||
89 | fprintf(stderr, "Error: module name too long: '%s'\n", p); | ||
90 | exit(1); | ||
91 | } | ||
92 | strcpy(modname, p); | ||
93 | } | ||
94 | |||
95 | static int find_ffofs(BuildCtx *ctx, const char *name) | ||
96 | { | ||
97 | int i; | ||
98 | for (i = 0; i < ctx->nglob; i++) { | ||
99 | const char *gl = ctx->globnames[i]; | ||
100 | if (gl[0] == 'f' && gl[1] == 'f' && gl[2] == '_' && !strcmp(gl+3, name)) { | ||
101 | return (int)((uint8_t *)ctx->glob[i] - ctx->code); | ||
102 | } | ||
103 | } | ||
104 | fprintf(stderr, "Error: undefined fast function %s%s\n", | ||
105 | LABEL_PREFIX_FF, name); | ||
106 | exit(1); | ||
107 | } | ||
108 | |||
109 | static void libdef_func(BuildCtx *ctx, char *p, int arg) | ||
110 | { | ||
111 | if (arg != LIBINIT_CF) | ||
112 | ffasmfunc++; | ||
113 | if (ctx->mode == BUILD_libdef) { | ||
114 | if (modstate == 0) { | ||
115 | fprintf(stderr, "Error: no module for function definition %s\n", p); | ||
116 | exit(1); | ||
117 | } | ||
118 | if (regfunc == REGFUNC_NOREG) { | ||
119 | if (optr+1 > obuf+sizeof(obuf)) { | ||
120 | fprintf(stderr, "Error: output buffer overflow\n"); | ||
121 | exit(1); | ||
122 | } | ||
123 | *optr++ = LIBINIT_FFID; | ||
124 | } else { | ||
125 | if (arg != LIBINIT_ASM_) { | ||
126 | if (modstate != 1) fprintf(ctx->fp, ",\n"); | ||
127 | modstate = 2; | ||
128 | fprintf(ctx->fp, " %s%s", arg ? LABEL_PREFIX_FFH : LABEL_PREFIX_CF, p); | ||
129 | } | ||
130 | if (regfunc != REGFUNC_NOREGUV) obuf[2]++; /* Bump hash table size. */ | ||
131 | libdef_name(regfunc == REGFUNC_NOREGUV ? "" : p, arg); | ||
132 | } | ||
133 | } else if (ctx->mode == BUILD_ffdef) { | ||
134 | fprintf(ctx->fp, "FFDEF(%s)\n", p); | ||
135 | } else if (ctx->mode == BUILD_recdef) { | ||
136 | if (strlen(p) > sizeof(funcname)-1) { | ||
137 | fprintf(stderr, "Error: function name too long: '%s'\n", p); | ||
138 | exit(1); | ||
139 | } | ||
140 | strcpy(funcname, p); | ||
141 | } else if (ctx->mode == BUILD_vmdef) { | ||
142 | int i; | ||
143 | for (i = 1; p[i] && modname[i-1]; i++) | ||
144 | if (p[i] == '_') p[i] = '.'; | ||
145 | fprintf(ctx->fp, "\"%s\",\n", p); | ||
146 | } else if (ctx->mode == BUILD_bcdef) { | ||
147 | if (arg != LIBINIT_CF) | ||
148 | fprintf(ctx->fp, ",\n%d", find_ffofs(ctx, p)); | ||
149 | } | ||
150 | ffid++; | ||
151 | regfunc = REGFUNC_OK; | ||
152 | } | ||
153 | |||
154 | static uint32_t find_rec(char *name) | ||
155 | { | ||
156 | char *p = (char *)obuf; | ||
157 | uint32_t n; | ||
158 | for (n = 2; *p; n++) { | ||
159 | if (strcmp(p, name) == 0) | ||
160 | return n; | ||
161 | p += strlen(p)+1; | ||
162 | } | ||
163 | if (p+strlen(name)+1 >= (char *)obuf+sizeof(obuf)) { | ||
164 | fprintf(stderr, "Error: output buffer overflow\n"); | ||
165 | exit(1); | ||
166 | } | ||
167 | strcpy(p, name); | ||
168 | return n; | ||
169 | } | ||
170 | |||
171 | static void libdef_rec(BuildCtx *ctx, char *p, int arg) | ||
172 | { | ||
173 | UNUSED(arg); | ||
174 | if (ctx->mode == BUILD_recdef) { | ||
175 | char *q; | ||
176 | uint32_t n; | ||
177 | for (; recffid+1 < ffid; recffid++) | ||
178 | fprintf(ctx->fp, ",\n0"); | ||
179 | recffid = ffid; | ||
180 | if (*p == '.') p = funcname; | ||
181 | q = strchr(p, ' '); | ||
182 | if (q) *q++ = '\0'; | ||
183 | n = find_rec(p); | ||
184 | if (q) | ||
185 | fprintf(ctx->fp, ",\n0x%02x00+(%s)", n, q); | ||
186 | else | ||
187 | fprintf(ctx->fp, ",\n0x%02x00", n); | ||
188 | } | ||
189 | } | ||
190 | |||
191 | static void memcpy_endian(void *dst, void *src, size_t n) | ||
192 | { | ||
193 | union { uint8_t b; uint32_t u; } host_endian; | ||
194 | host_endian.u = 1; | ||
195 | if (host_endian.b == LJ_ENDIAN_SELECT(1, 0)) { | ||
196 | memcpy(dst, src, n); | ||
197 | } else { | ||
198 | size_t i; | ||
199 | for (i = 0; i < n; i++) | ||
200 | ((uint8_t *)dst)[i] = ((uint8_t *)src)[n-i-1]; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | static void libdef_push(BuildCtx *ctx, char *p, int arg) | ||
205 | { | ||
206 | UNUSED(arg); | ||
207 | if (ctx->mode == BUILD_libdef) { | ||
208 | int len = (int)strlen(p); | ||
209 | if (*p == '"') { | ||
210 | if (len > 1 && p[len-1] == '"') { | ||
211 | p[len-1] = '\0'; | ||
212 | libdef_name(p+1, LIBINIT_STRING); | ||
213 | return; | ||
214 | } | ||
215 | } else if (*p >= '0' && *p <= '9') { | ||
216 | char *ep; | ||
217 | double d = strtod(p, &ep); | ||
218 | if (*ep == '\0') { | ||
219 | if (optr+1+sizeof(double) > obuf+sizeof(obuf)) { | ||
220 | fprintf(stderr, "Error: output buffer overflow\n"); | ||
221 | exit(1); | ||
222 | } | ||
223 | *optr++ = LIBINIT_NUMBER; | ||
224 | memcpy_endian(optr, &d, sizeof(double)); | ||
225 | optr += sizeof(double); | ||
226 | return; | ||
227 | } | ||
228 | } else if (!strcmp(p, "lastcl")) { | ||
229 | if (optr+1 > obuf+sizeof(obuf)) { | ||
230 | fprintf(stderr, "Error: output buffer overflow\n"); | ||
231 | exit(1); | ||
232 | } | ||
233 | *optr++ = LIBINIT_LASTCL; | ||
234 | return; | ||
235 | } else if (len > 4 && !strncmp(p, "top-", 4)) { | ||
236 | if (optr+2 > obuf+sizeof(obuf)) { | ||
237 | fprintf(stderr, "Error: output buffer overflow\n"); | ||
238 | exit(1); | ||
239 | } | ||
240 | *optr++ = LIBINIT_COPY; | ||
241 | *optr++ = (uint8_t)atoi(p+4); | ||
242 | return; | ||
243 | } | ||
244 | fprintf(stderr, "Error: bad value for %sPUSH(%s)\n", LIBDEF_PREFIX, p); | ||
245 | exit(1); | ||
246 | } | ||
247 | } | ||
248 | |||
249 | static void libdef_set(BuildCtx *ctx, char *p, int arg) | ||
250 | { | ||
251 | UNUSED(arg); | ||
252 | if (ctx->mode == BUILD_libdef) { | ||
253 | if (p[0] == '!' && p[1] == '\0') p[0] = '\0'; /* Set env. */ | ||
254 | libdef_name(p, LIBINIT_STRING); | ||
255 | *optr++ = LIBINIT_SET; | ||
256 | obuf[2]++; /* Bump hash table size. */ | ||
257 | } | ||
258 | } | ||
259 | |||
260 | static void libdef_regfunc(BuildCtx *ctx, char *p, int arg) | ||
261 | { | ||
262 | UNUSED(ctx); UNUSED(p); | ||
263 | regfunc = arg; | ||
264 | } | ||
265 | |||
266 | typedef void (*LibDefFunc)(BuildCtx *ctx, char *p, int arg); | ||
267 | |||
268 | typedef struct LibDefHandler { | ||
269 | const char *suffix; | ||
270 | const char *stop; | ||
271 | const LibDefFunc func; | ||
272 | const int arg; | ||
273 | } LibDefHandler; | ||
274 | |||
275 | static const LibDefHandler libdef_handlers[] = { | ||
276 | { "MODULE_", " \t\r\n", libdef_module, 0 }, | ||
277 | { "CF(", ")", libdef_func, LIBINIT_CF }, | ||
278 | { "ASM(", ")", libdef_func, LIBINIT_ASM }, | ||
279 | { "ASM_(", ")", libdef_func, LIBINIT_ASM_ }, | ||
280 | { "REC(", ")", libdef_rec, 0 }, | ||
281 | { "PUSH(", ")", libdef_push, 0 }, | ||
282 | { "SET(", ")", libdef_set, 0 }, | ||
283 | { "NOREGUV", NULL, libdef_regfunc, REGFUNC_NOREGUV }, | ||
284 | { "NOREG", NULL, libdef_regfunc, REGFUNC_NOREG }, | ||
285 | { NULL, NULL, (LibDefFunc)0, 0 } | ||
286 | }; | ||
287 | |||
288 | /* Emit C source code for library function definitions. */ | ||
289 | void emit_lib(BuildCtx *ctx) | ||
290 | { | ||
291 | const char *fname; | ||
292 | |||
293 | if (ctx->mode == BUILD_ffdef || ctx->mode == BUILD_libdef || | ||
294 | ctx->mode == BUILD_recdef) | ||
295 | fprintf(ctx->fp, "/* This is a generated file. DO NOT EDIT! */\n\n"); | ||
296 | else if (ctx->mode == BUILD_vmdef) | ||
297 | fprintf(ctx->fp, "ffnames = {\n[0]=\"Lua\",\n\"C\",\n"); | ||
298 | if (ctx->mode == BUILD_recdef) | ||
299 | fprintf(ctx->fp, "static const uint16_t recff_idmap[] = {\n0,\n0x0100"); | ||
300 | recffid = ffid = FF_C+1; | ||
301 | ffasmfunc = 0; | ||
302 | |||
303 | while ((fname = *ctx->args++)) { | ||
304 | char buf[256]; /* We don't care about analyzing lines longer than that. */ | ||
305 | FILE *fp; | ||
306 | if (fname[0] == '-' && fname[1] == '\0') { | ||
307 | fp = stdin; | ||
308 | } else { | ||
309 | fp = fopen(fname, "r"); | ||
310 | if (!fp) { | ||
311 | fprintf(stderr, "Error: cannot open input file '%s': %s\n", | ||
312 | fname, strerror(errno)); | ||
313 | exit(1); | ||
314 | } | ||
315 | } | ||
316 | modstate = 0; | ||
317 | regfunc = REGFUNC_OK; | ||
318 | while (fgets(buf, sizeof(buf), fp) != NULL) { | ||
319 | char *p; | ||
320 | for (p = buf; (p = strstr(p, LIBDEF_PREFIX)) != NULL; ) { | ||
321 | const LibDefHandler *ldh; | ||
322 | p += sizeof(LIBDEF_PREFIX)-1; | ||
323 | for (ldh = libdef_handlers; ldh->suffix != NULL; ldh++) { | ||
324 | size_t n, len = strlen(ldh->suffix); | ||
325 | if (!strncmp(p, ldh->suffix, len)) { | ||
326 | p += len; | ||
327 | n = ldh->stop ? strcspn(p, ldh->stop) : 0; | ||
328 | if (!p[n]) break; | ||
329 | p[n] = '\0'; | ||
330 | ldh->func(ctx, p, ldh->arg); | ||
331 | p += n+1; | ||
332 | break; | ||
333 | } | ||
334 | } | ||
335 | if (ldh->suffix == NULL) { | ||
336 | buf[strlen(buf)-1] = '\0'; | ||
337 | fprintf(stderr, "Error: unknown library definition tag %s%s\n", | ||
338 | LIBDEF_PREFIX, p); | ||
339 | exit(1); | ||
340 | } | ||
341 | } | ||
342 | } | ||
343 | fclose(fp); | ||
344 | if (ctx->mode == BUILD_libdef) { | ||
345 | libdef_endmodule(ctx); | ||
346 | } | ||
347 | } | ||
348 | |||
349 | if (ctx->mode == BUILD_ffdef) { | ||
350 | fprintf(ctx->fp, "\n#undef FFDEF\n\n"); | ||
351 | fprintf(ctx->fp, | ||
352 | "#ifndef FF_NUM_ASMFUNC\n#define FF_NUM_ASMFUNC %d\n#endif\n\n", | ||
353 | ffasmfunc); | ||
354 | } else if (ctx->mode == BUILD_vmdef) { | ||
355 | fprintf(ctx->fp, "}\n\n"); | ||
356 | } else if (ctx->mode == BUILD_bcdef) { | ||
357 | int i; | ||
358 | fprintf(ctx->fp, "\n};\n\n"); | ||
359 | fprintf(ctx->fp, "LJ_DATADEF const uint16_t lj_bc_mode[] = {\n"); | ||
360 | fprintf(ctx->fp, "BCDEF(BCMODE)\n"); | ||
361 | for (i = ffasmfunc-1; i > 0; i--) | ||
362 | fprintf(ctx->fp, "BCMODE_FF,\n"); | ||
363 | fprintf(ctx->fp, "BCMODE_FF\n};\n\n"); | ||
364 | } else if (ctx->mode == BUILD_recdef) { | ||
365 | char *p = (char *)obuf; | ||
366 | fprintf(ctx->fp, "\n};\n\n"); | ||
367 | fprintf(ctx->fp, "static const RecordFunc recff_func[] = {\n" | ||
368 | "recff_nyi,\n" | ||
369 | "recff_c"); | ||
370 | while (*p) { | ||
371 | fprintf(ctx->fp, ",\nrecff_%s", p); | ||
372 | p += strlen(p)+1; | ||
373 | } | ||
374 | fprintf(ctx->fp, "\n};\n\n"); | ||
375 | } | ||
376 | } | ||
377 | |||