2 ** LuaJIT VM builder: library definition compiler.
3 ** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
10 /* Context for library definitions. */
11 static uint8_t obuf
[8192];
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
;
25 static void libdef_name(const char *p
, int kind
)
28 if (kind
!= LIBINIT_STRING
) {
29 if (n
> modnamelen
&& p
[modnamelen
] == '_' &&
30 !strncmp(p
, modname
, modnamelen
)) {
35 if (n
> LIBINIT_MAXSTR
) {
36 fprintf(stderr
, "Error: string too long: '%s'\n", p
);
39 if (optr
+1+n
+2 > obuf
+sizeof(obuf
)) { /* +2 for caller. */
40 fprintf(stderr
, "Error: output buffer overflow\n");
43 *optr
++ = (uint8_t)(n
| kind
);
48 static void libdef_endmodule(BuildCtx
*ctx
)
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
);
60 for (n
= 0, p
= obuf
; p
< optr
; p
++) {
61 n
+= sprintf(line
+n
, "%d,", *p
);
63 fprintf(ctx
->fp
, "%s\n", line
);
68 fprintf(ctx
->fp
, "%s%d\n};\n#endif\n\n", line
, LIBINIT_END
);
72 static void libdef_module(BuildCtx
*ctx
, char *p
, int arg
)
75 if (ctx
->mode
== BUILD_libdef
) {
76 libdef_endmodule(ctx
);
78 *optr
++ = (uint8_t)ffid
;
79 *optr
++ = (uint8_t)ffasmfunc
;
80 *optr
++ = 0; /* Hash table size. */
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
);
87 modnamelen
= strlen(p
);
88 if (modnamelen
> sizeof(modname
)-1) {
89 fprintf(stderr
, "Error: module name too long: '%s'\n", p
);
95 static int find_ffofs(BuildCtx
*ctx
, const char *name
)
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
);
104 fprintf(stderr
, "Error: undefined fast function %s%s\n",
105 LABEL_PREFIX_FF
, name
);
109 static void libdef_func(BuildCtx
*ctx
, char *p
, int arg
)
111 if (arg
!= LIBINIT_CF
)
113 if (ctx
->mode
== BUILD_libdef
) {
115 fprintf(stderr
, "Error: no module for function definition %s\n", p
);
118 if (regfunc
== REGFUNC_NOREG
) {
119 if (optr
+1 > obuf
+sizeof(obuf
)) {
120 fprintf(stderr
, "Error: output buffer overflow\n");
123 *optr
++ = LIBINIT_FFID
;
125 if (arg
!= LIBINIT_ASM_
) {
126 if (modstate
!= 1) fprintf(ctx
->fp
, ",\n");
128 fprintf(ctx
->fp
, " %s%s", arg
? LABEL_PREFIX_FFH
: LABEL_PREFIX_CF
, p
);
130 if (regfunc
!= REGFUNC_NOREGUV
) obuf
[2]++; /* Bump hash table size. */
131 libdef_name(regfunc
== REGFUNC_NOREGUV
? "" : p
, arg
);
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
);
141 } else if (ctx
->mode
== BUILD_vmdef
) {
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
));
151 regfunc
= REGFUNC_OK
;
154 static uint32_t find_rec(char *name
)
156 char *p
= (char *)obuf
;
158 for (n
= 2; *p
; n
++) {
159 if (strcmp(p
, name
) == 0)
163 if (p
+strlen(name
)+1 >= (char *)obuf
+sizeof(obuf
)) {
164 fprintf(stderr
, "Error: output buffer overflow\n");
171 static void libdef_rec(BuildCtx
*ctx
, char *p
, int arg
)
174 if (ctx
->mode
== BUILD_recdef
) {
177 for (; recffid
+1 < ffid
; recffid
++)
178 fprintf(ctx
->fp
, ",\n0");
180 if (*p
== '.') p
= funcname
;
185 fprintf(ctx
->fp
, ",\n0x%02x00+(%s)", n
, q
);
187 fprintf(ctx
->fp
, ",\n0x%02x00", n
);
191 static void memcpy_endian(void *dst
, void *src
, size_t n
)
193 union { uint8_t b
; uint32_t u
; } host_endian
;
195 if (host_endian
.b
== LJ_ENDIAN_SELECT(1, 0)) {
199 for (i
= 0; i
< n
; i
++)
200 ((uint8_t *)dst
)[i
] = ((uint8_t *)src
)[n
-i
-1];
204 static void libdef_push(BuildCtx
*ctx
, char *p
, int arg
)
207 if (ctx
->mode
== BUILD_libdef
) {
208 int len
= (int)strlen(p
);
210 if (len
> 1 && p
[len
-1] == '"') {
212 libdef_name(p
+1, LIBINIT_STRING
);
215 } else if (*p
>= '0' && *p
<= '9') {
217 double d
= strtod(p
, &ep
);
219 if (optr
+1+sizeof(double) > obuf
+sizeof(obuf
)) {
220 fprintf(stderr
, "Error: output buffer overflow\n");
223 *optr
++ = LIBINIT_NUMBER
;
224 memcpy_endian(optr
, &d
, sizeof(double));
225 optr
+= sizeof(double);
228 } else if (!strcmp(p
, "lastcl")) {
229 if (optr
+1 > obuf
+sizeof(obuf
)) {
230 fprintf(stderr
, "Error: output buffer overflow\n");
233 *optr
++ = LIBINIT_LASTCL
;
235 } else if (len
> 4 && !strncmp(p
, "top-", 4)) {
236 if (optr
+2 > obuf
+sizeof(obuf
)) {
237 fprintf(stderr
, "Error: output buffer overflow\n");
240 *optr
++ = LIBINIT_COPY
;
241 *optr
++ = (uint8_t)atoi(p
+4);
244 fprintf(stderr
, "Error: bad value for %sPUSH(%s)\n", LIBDEF_PREFIX
, p
);
249 static void libdef_set(BuildCtx
*ctx
, char *p
, int 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. */
260 static void libdef_regfunc(BuildCtx
*ctx
, char *p
, int arg
)
262 UNUSED(ctx
); UNUSED(p
);
266 typedef void (*LibDefFunc
)(BuildCtx
*ctx
, char *p
, int arg
);
268 typedef struct LibDefHandler
{
271 const LibDefFunc func
;
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 }
288 /* Emit C source code for library function definitions. */
289 void emit_lib(BuildCtx
*ctx
)
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;
303 while ((fname
= *ctx
->args
++)) {
304 char buf
[256]; /* We don't care about analyzing lines longer than that. */
306 if (fname
[0] == '-' && fname
[1] == '\0') {
309 fp
= fopen(fname
, "r");
311 fprintf(stderr
, "Error: cannot open input file '%s': %s\n",
312 fname
, strerror(errno
));
317 regfunc
= REGFUNC_OK
;
318 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
320 /* Simplistic pre-processor. Only handles top-level #if/#endif. */
321 if (buf
[0] == '#' && buf
[1] == 'i' && buf
[2] == 'f') {
323 if (!strcmp(buf
, "#if LJ_52\n"))
325 else if (!strcmp(buf
, "#if LJ_HASJIT\n"))
327 else if (!strcmp(buf
, "#if LJ_HASFFI\n"))
331 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
332 if (buf
[0] == '#' && buf
[1] == 'e' && buf
[2] == 'n') {
333 if (--lvl
== 0) break;
334 } else if (buf
[0] == '#' && buf
[1] == 'i' && buf
[2] == 'f') {
341 for (p
= buf
; (p
= strstr(p
, LIBDEF_PREFIX
)) != NULL
; ) {
342 const LibDefHandler
*ldh
;
343 p
+= sizeof(LIBDEF_PREFIX
)-1;
344 for (ldh
= libdef_handlers
; ldh
->suffix
!= NULL
; ldh
++) {
345 size_t n
, len
= strlen(ldh
->suffix
);
346 if (!strncmp(p
, ldh
->suffix
, len
)) {
348 n
= ldh
->stop
? strcspn(p
, ldh
->stop
) : 0;
351 ldh
->func(ctx
, p
, ldh
->arg
);
356 if (ldh
->suffix
== NULL
) {
357 buf
[strlen(buf
)-1] = '\0';
358 fprintf(stderr
, "Error: unknown library definition tag %s%s\n",
365 if (ctx
->mode
== BUILD_libdef
) {
366 libdef_endmodule(ctx
);
370 if (ctx
->mode
== BUILD_ffdef
) {
371 fprintf(ctx
->fp
, "\n#undef FFDEF\n\n");
373 "#ifndef FF_NUM_ASMFUNC\n#define FF_NUM_ASMFUNC %d\n#endif\n\n",
375 } else if (ctx
->mode
== BUILD_vmdef
) {
376 fprintf(ctx
->fp
, "}\n\n");
377 } else if (ctx
->mode
== BUILD_bcdef
) {
379 fprintf(ctx
->fp
, "\n};\n\n");
380 fprintf(ctx
->fp
, "LJ_DATADEF const uint16_t lj_bc_mode[] = {\n");
381 fprintf(ctx
->fp
, "BCDEF(BCMODE)\n");
382 for (i
= ffasmfunc
-1; i
> 0; i
--)
383 fprintf(ctx
->fp
, "BCMODE_FF,\n");
384 fprintf(ctx
->fp
, "BCMODE_FF\n};\n\n");
385 } else if (ctx
->mode
== BUILD_recdef
) {
386 char *p
= (char *)obuf
;
387 fprintf(ctx
->fp
, "\n};\n\n");
388 fprintf(ctx
->fp
, "static const RecordFunc recff_func[] = {\n"
392 fprintf(ctx
->fp
, ",\nrecff_%s", p
);
395 fprintf(ctx
->fp
, "\n};\n\n");