15
15
#include "ngx_http_lua_clfactory.h"
18
#define CLFACTORY_BEGIN_CODE "return function() "
19
#define CLFACTORY_BEGIN_SIZE (sizeof(CLFACTORY_BEGIN_CODE) - 1)
21
#define CLFACTORY_END_CODE "\nend"
22
#define CLFACTORY_END_SIZE (sizeof(CLFACTORY_END_CODE) - 1)
19
26
* taken from chaoslawful:
20
27
* Lua bytecode header Luajit bytecode header
216
223
* ---------------------
219
/* bytecode for luajit */
220
#define LJ_LITTLE_ENDIAN_CODE_STRIPPED \
221
"\x14\x03\x00\x01\x00\x01\x00\x03" \
222
"\x31\x00\x00\x00\x30\x00\x00\x80\x48\x00\x02\x00" \
224
#define LJ_BIG_ENDIAN_CODE_STRIPPED \
225
"\x14\x03\x00\x01\x00\x01\x00\x03" \
226
"\x00\x00\x00\x31\x80\x00\x00\x30\x00\x02\x00\x48" \
228
#define LJ_LITTLE_ENDIAN_CODE \
229
"\x15\x03\x00\x01\x00\x01\x00\x03\x00" \
230
"\x31\x00\x00\x00\x30\x00\x00\x80\x48\x00\x02\x00" \
232
#define LJ_BIG_ENDIAN_CODE \
233
"\x15\x03\x00\x01\x00\x01\x00\x03\x00" \
234
"\x00\x00\x00\x31\x80\x00\x00\x30\x00\x02\x00\x48" \
226
/* bytecode for luajit 2.0 */
228
#define LJ20_LITTLE_ENDIAN_CODE_STRIPPED \
229
"\x14\x03\x00\x01\x00\x01\x00\x03" \
230
"\x31\x00\x00\x00\x30\x00\x00\x80\x48\x00\x02\x00" \
233
#define LJ20_BIG_ENDIAN_CODE_STRIPPED \
234
"\x14\x03\x00\x01\x00\x01\x00\x03" \
235
"\x00\x00\x00\x31\x80\x00\x00\x30\x00\x02\x00\x48" \
238
#define LJ20_LITTLE_ENDIAN_CODE \
239
"\x15\x03\x00\x01\x00\x01\x00\x03\x00" \
240
"\x31\x00\x00\x00\x30\x00\x00\x80\x48\x00\x02\x00" \
243
#define LJ20_BIG_ENDIAN_CODE \
244
"\x15\x03\x00\x01\x00\x01\x00\x03\x00" \
245
"\x00\x00\x00\x31\x80\x00\x00\x30\x00\x02\x00\x48" \
248
/* bytecode for luajit 2.1 */
250
#define LJ21_LITTLE_ENDIAN_CODE_STRIPPED \
251
"\x14\x03\x00\x01\x00\x01\x00\x03" \
252
"\x33\x00\x00\x00\x32\x00\x00\x80\x4c\x00\x02\x00" \
255
#define LJ21_BIG_ENDIAN_CODE_STRIPPED \
256
"\x14\x03\x00\x01\x00\x01\x00\x03" \
257
"\x00\x00\x00\x33\x80\x00\x00\x32\x00\x02\x00\x4c" \
260
#define LJ21_LITTLE_ENDIAN_CODE \
261
"\x15\x03\x00\x01\x00\x01\x00\x03\x00" \
262
"\x33\x00\x00\x00\x32\x00\x00\x80\x4c\x00\x02\x00" \
265
#define LJ21_BIG_ENDIAN_CODE \
266
"\x15\x03\x00\x01\x00\x01\x00\x03\x00" \
267
"\x00\x00\x00\x33\x80\x00\x00\x32\x00\x02\x00\x4c" \
237
270
#define LJ_CODE_LEN 23
239
272
#define LJ_HEADERSIZE 5
240
273
#define LJ_BCDUMP_F_BE 0x01
241
274
#define LJ_BCDUMP_F_STRIP 0x02
242
#define LJ_BCDUMP_VERSION 1
275
#define LJ21_BCDUMP_VERSION 2
276
#define LJ20_BCDUMP_VERSION 1
243
277
#define LJ_SIGNATURE "\x1b\x4c\x4a"
279
} clfactory_buffer_ctx_t;
282
static const char *clfactory_getF(lua_State *L, void *ud, size_t *size);
283
static int clfactory_errfile(lua_State *L, const char *what, int fname_index);
284
static const char *clfactory_getS(lua_State *L, void *ud, size_t *size);
314
} ngx_http_lua_clfactory_buffer_ctx_t;
317
static const char *ngx_http_lua_clfactory_getF(lua_State *L, void *ud,
319
static int ngx_http_lua_clfactory_errfile(lua_State *L, const char *what,
321
static const char *ngx_http_lua_clfactory_getS(lua_State *L, void *ud,
323
static long ngx_http_lua_clfactory_file_size(FILE *f);
288
ngx_http_lua_clfactory_bytecode_prepare(lua_State *L, clfactory_file_ctx_t *lf,
327
ngx_http_lua_clfactory_bytecode_prepare(lua_State *L,
328
ngx_http_lua_clfactory_file_ctx_t *lf, int fname_index)
291
330
int x = 1, size_of_int, size_of_size_t, little_endian,
292
331
size_of_inst, version, stripped;
293
332
static int num_of_inst = 3, num_of_inter_func = 1;
294
333
const char *filename, *emsg, *serr, *bytecode;
295
334
size_t size, bytecode_len;
311
350
version = *(lf->begin_code.str + 3);
352
dd("version: %d", (int) version);
313
354
if (ngx_memcmp(lf->begin_code.str, LJ_SIGNATURE,
314
sizeof(LJ_SIGNATURE) - 1)
315
|| version != LJ_BCDUMP_VERSION)
355
sizeof(LJ_SIGNATURE) - 1))
317
357
emsg = "bad byte-code header";
333
373
little_endian = !((*(lf->begin_code.str + 4)) & LJ_BCDUMP_F_BE);
334
374
stripped = (*(lf->begin_code.str + 4)) & LJ_BCDUMP_F_STRIP;
338
lf->end_code.ptr = LJ_LITTLE_ENDIAN_CODE_STRIPPED;
341
lf->end_code.ptr = LJ_BIG_ENDIAN_CODE_STRIPPED;
344
lf->end_code_len = LJ_CODE_LEN_STRIPPED;
376
dd("stripped: %d", (int) stripped);
378
if (version == LJ21_BCDUMP_VERSION) {
381
lf->end_code.ptr = LJ21_LITTLE_ENDIAN_CODE_STRIPPED;
384
lf->end_code.ptr = LJ21_BIG_ENDIAN_CODE_STRIPPED;
387
lf->end_code_len = LJ_CODE_LEN_STRIPPED;
391
lf->end_code.ptr = LJ21_LITTLE_ENDIAN_CODE;
394
lf->end_code.ptr = LJ21_BIG_ENDIAN_CODE;
397
lf->end_code_len = LJ_CODE_LEN;
400
} else if (version == LJ20_BCDUMP_VERSION) {
403
lf->end_code.ptr = LJ20_LITTLE_ENDIAN_CODE_STRIPPED;
406
lf->end_code.ptr = LJ20_BIG_ENDIAN_CODE_STRIPPED;
409
lf->end_code_len = LJ_CODE_LEN_STRIPPED;
413
lf->end_code.ptr = LJ20_LITTLE_ENDIAN_CODE;
416
lf->end_code.ptr = LJ20_BIG_ENDIAN_CODE;
419
lf->end_code_len = LJ_CODE_LEN;
348
lf->end_code.ptr = LJ_LITTLE_ENDIAN_CODE;
351
lf->end_code.ptr = LJ_BIG_ENDIAN_CODE;
354
lf->end_code_len = LJ_CODE_LEN;
423
emsg = "bytecode format version unsupported";
357
if (ngx_fd_info(fileno(lf->f), &fi) == NGX_FILE_ERROR) {
427
fsize = ngx_http_lua_clfactory_file_size(lf->f);
358
429
serr = strerror(errno);
359
emsg = "cannot fstat";
430
emsg = "cannot fseek/ftell";
363
lf->rest_len = ngx_file_size(&fi) - LJ_HEADERSIZE;
434
lf->rest_len = fsize - LJ_HEADERSIZE;
365
436
#if defined(DDEBUG) && (DDEBUG)
544
614
lf.end_code.ptr = CLFACTORY_END_CODE;
545
615
lf.end_code_len = CLFACTORY_END_SIZE;
547
if (filename == NULL) {
548
lua_pushliteral(L, "=stdin");
552
lua_pushfstring(L, "@%s", filename);
553
lf.f = fopen(filename, "r");
556
return clfactory_errfile(L, "open", fname_index);
617
lua_pushfstring(L, "@%s", filename);
619
lf.f = fopen(filename, "r");
621
return ngx_http_lua_clfactory_errfile(L, "open", fname_index);
577
641
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
579
643
if (lf.f == NULL) {
580
return clfactory_errfile(L, "reopen", fname_index);
644
return ngx_http_lua_clfactory_errfile(L, "reopen", fname_index);
583
647
/* check whether lib jit exists */
632
696
lf.sent_begin = lf.sent_end = 0;
633
status = lua_load(L, clfactory_getF, &lf, lua_tostring(L, -1));
697
status = lua_load(L, ngx_http_lua_clfactory_getF, &lf,
698
lua_tostring(L, -1));
635
700
readstatus = ferror(lf.f);
641
706
if (readstatus) {
642
707
lua_settop(L, fname_index); /* ignore results from `lua_load' */
643
return clfactory_errfile(L, "read", fname_index);
708
return ngx_http_lua_clfactory_errfile(L, "read", fname_index);
646
711
lua_remove(L, fname_index);
653
ngx_http_lua_clfactory_loadstring(lua_State *L, const char *s)
655
return ngx_http_lua_clfactory_loadbuffer(L, s, strlen(s), s);
660
718
ngx_http_lua_clfactory_loadbuffer(lua_State *L, const char *buff,
661
size_t size, const char *name)
719
size_t size, const char *name)
663
clfactory_buffer_ctx_t ls;
721
ngx_http_lua_clfactory_buffer_ctx_t ls;
667
725
ls.sent_begin = 0;
670
return lua_load(L, clfactory_getS, &ls, name);
728
return lua_load(L, ngx_http_lua_clfactory_getS, &ls, name);
674
732
static const char *
675
clfactory_getF(lua_State *L, void *ud, size_t *size)
733
ngx_http_lua_clfactory_getF(lua_State *L, void *ud, size_t *size)
679
clfactory_file_ctx_t *lf;
681
lf = (clfactory_file_ctx_t *) ud;
738
ngx_http_lua_clfactory_file_ctx_t *lf;
740
lf = (ngx_http_lua_clfactory_file_ctx_t *) ud;
683
742
if (lf->extraline) {
684
743
lf->extraline = 0;
767
826
static const char *
768
clfactory_getS(lua_State *L, void *ud, size_t *size)
827
ngx_http_lua_clfactory_getS(lua_State *L, void *ud, size_t *size)
770
clfactory_buffer_ctx_t *ls = ud;
829
ngx_http_lua_clfactory_buffer_ctx_t *ls = ud;
772
831
if (ls->sent_begin == 0) {
773
832
ls->sent_begin = 1;
856
ngx_http_lua_clfactory_file_size(FILE *f)
865
if (fseek(f, 0, SEEK_END) != 0) {
874
if (fseek(f, cur_pos, SEEK_SET) != 0) {
795
882
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */