2
** LuaJIT VM builder: library definition compiler.
3
** Copyright (C) 2005-2011 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
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)) {
327
n = ldh->stop ? strcspn(p, ldh->stop) : 0;
330
ldh->func(ctx, p, ldh->arg);
335
if (ldh->suffix == NULL) {
336
buf[strlen(buf)-1] = '\0';
337
fprintf(stderr, "Error: unknown library definition tag %s%s\n",
344
if (ctx->mode == BUILD_libdef) {
345
libdef_endmodule(ctx);
349
if (ctx->mode == BUILD_ffdef) {
350
fprintf(ctx->fp, "\n#undef FFDEF\n\n");
352
"#ifndef FF_NUM_ASMFUNC\n#define FF_NUM_ASMFUNC %d\n#endif\n\n",
354
} else if (ctx->mode == BUILD_vmdef) {
355
fprintf(ctx->fp, "}\n\n");
356
} else if (ctx->mode == BUILD_bcdef) {
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"
371
fprintf(ctx->fp, ",\nrecff_%s", p);
374
fprintf(ctx->fp, "\n};\n\n");