aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/LuaJIT-1.1.7/src/ljitlib.c
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-01-23 23:36:30 +1000
committerDavid Walter Seikel2012-01-23 23:36:30 +1000
commit6523585c66c04cea54df50013df8886b589847d8 (patch)
tree0b22aee7064166d88595eda260ca2d17c0773da5 /libraries/LuaJIT-1.1.7/src/ljitlib.c
parentUpdate the EFL to what I'm actually using, coz I'm using some stuff not yet r... (diff)
downloadSledjHamr-6523585c66c04cea54df50013df8886b589847d8.zip
SledjHamr-6523585c66c04cea54df50013df8886b589847d8.tar.gz
SledjHamr-6523585c66c04cea54df50013df8886b589847d8.tar.bz2
SledjHamr-6523585c66c04cea54df50013df8886b589847d8.tar.xz
Add luaproc and LuaJIT libraries.
Two versions of LuaJIT, the stable release, and the dev version. Try the dev version first, until ih fails badly.
Diffstat (limited to 'libraries/LuaJIT-1.1.7/src/ljitlib.c')
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljitlib.c637
1 files changed, 637 insertions, 0 deletions
diff --git a/libraries/LuaJIT-1.1.7/src/ljitlib.c b/libraries/LuaJIT-1.1.7/src/ljitlib.c
new file mode 100644
index 0000000..4efc04d
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/src/ljitlib.c
@@ -0,0 +1,637 @@
1/*
2** Lua library for the JIT engine.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#include <stdio.h>
7#include <string.h>
8
9#define ljitlib_c
10#define LUA_LIB
11
12#include "lua.h"
13#include "lauxlib.h"
14#include "luajit.h"
15#include "lualib.h"
16
17/* This file is not a pure C API user. Some internals are required. */
18#include "lobject.h"
19#include "lstate.h"
20#include "lstring.h"
21#include "ltable.h"
22#include "lfunc.h"
23#include "lgc.h"
24#include "lopcodes.h"
25
26#include "ljit.h"
27#include "ljit_hints.h"
28
29#define STRING_HINTS
30#include "ljit_hints.h"
31
32/* ------------------------------------------------------------------------ */
33
34/* Static pointer addresses used as registry keys. */
35/* The values do not matter, but must be different to prevent joining. */
36static const int regkey_frontend = 0x6c6a6c01;
37static const int regkey_comthread = 0x6c6a6c02;
38
39/* Check that the first argument is a Lua function and return its closure. */
40static Closure *check_LCL(lua_State *L)
41{
42 StkId o = L->base;
43 switch (lua_type(L, 1)) {
44 case LUA_TBOOLEAN:
45 o = (L->ci-1)->func;
46 case LUA_TFUNCTION:
47 if (isLfunction(o))
48 return clvalue(o);
49 break;
50 }
51 luaL_argerror(L, 1, "Lua function expected");
52 return NULL;
53}
54
55/* Create a new closure from a prototype. */
56/* Note: upvalues are assumed to be after first two slots. */
57static void push_LCL(lua_State *L, Proto *pt, Table *env)
58{
59 Closure *cl;
60 int i, nup = pt->nups;
61 /* Adjust the number of stack slots to the number of upvalues. */
62 luaL_checkstack(L, nup, "too many upvalues");
63 lua_settop(L, 2+nup);
64 /* Create a closure from the subroutine prototype. */
65 cl = luaF_newLclosure(L, nup, env);
66 cl->l.p = pt;
67 /* Allocate new upvalues and close them. */
68 for (i = 0; i < nup; i++)
69 cl->l.upvals[i] = luaF_findupval(L, L->base + (2+i));
70 luaF_close(L, L->base + 2);
71 lua_settop(L, 2); /* Remove upvalues. */
72 setclvalue(L, L->top++, cl); /* Return closure on top of stack. */
73 luaC_checkGC(L);
74}
75
76/* ------------------------------------------------------------------------ */
77
78/* Set JIT mode for the engine or a closure and/or its subroutines. */
79static int setmode(lua_State *L, int mode)
80{
81 int idx = 0;
82 switch (lua_type(L, 1)) {
83 case LUA_TNONE: /* jit.on/off() */
84 case LUA_TNIL: /* jit.on/off(nil) */
85 luaJIT_setmode(L, 0, mode | LUAJIT_MODE_ENGINE);
86 break;
87 case LUA_TFUNCTION: /* jit.on/off(func, nil|true|false) */
88 idx = 1;
89 case LUA_TBOOLEAN: /* jit.on/off(true, nil|true|false) (parent frame) */
90 if (lua_isboolean(L, 2))
91 mode |= lua_toboolean(L, 2)?LUAJIT_MODE_ALLFUNC:LUAJIT_MODE_ALLSUBFUNC;
92 else
93 mode |= LUAJIT_MODE_FUNC;
94 if (luaJIT_setmode(L, idx, mode) == 1) /* Ok? */
95 break;
96 default:
97 luaL_argerror(L, 1, "Lua function expected");
98 break;
99 }
100 return 0;
101}
102
103/* Set JIT mode to on: (re-)enable compilation. */
104static int j_on(lua_State *L)
105{
106 return setmode(L, LUAJIT_MODE_ON);
107}
108
109/* Set JIT mode to off: disable compilation. */
110static int j_off(lua_State *L)
111{
112 return setmode(L, LUAJIT_MODE_OFF);
113}
114
115/* Set JIT debug level. Defaults to maximum level for use with -j. */
116static int j_debug(lua_State *L)
117{
118 luaJIT_setmode(L, luaL_optinteger(L, 1, 100), LUAJIT_MODE_DEBUG);
119 return 0;
120}
121
122/* ------------------------------------------------------------------------ */
123
124/* Report the compilation status. */
125static int compstatus(lua_State *L, int status)
126{
127 if (status == -1)
128 return luaL_argerror(L, 1, "Lua function expected");
129 else if (status == JIT_S_OK)
130 return 0;
131 else {
132 lua_pushinteger(L, status);
133 return 1;
134 }
135}
136
137/* Compile a function. Pass typical args to help the optimizer. */
138static int j_compile(lua_State *L)
139{
140 int nargs = lua_gettop(L) - 1;
141 return compstatus(L, nargs >= 0 ? luaJIT_compile(L, nargs) : -1);
142}
143
144/* Recursively compile all subroutine prototypes. */
145static int rec_compile(lua_State *L, Proto *pt, Table *env, int stoponerror)
146{
147 int rstatus = JIT_S_OK;
148 int i;
149 for (i = 0; i < pt->sizep; i++) {
150 Proto *pti = pt->p[i];
151 int status;
152 push_LCL(L, pti, env); /* Assumes stack is at 2 (no upvalues). */
153 status = luaJIT_compile(L, 0);
154 lua_settop(L, 2); /* Clear stack */
155 if (status != JIT_S_OK) {
156 rstatus = status;
157 if (stoponerror) break;
158 }
159 status = rec_compile(L, pti, env, stoponerror);
160 if (status != JIT_S_OK) {
161 rstatus = status;
162 if (stoponerror) break;
163 }
164 }
165 return rstatus;
166}
167
168/* Compile all subroutines of a function. */
169/* Note: the function itself is _not_ compiled (use jit.compile()). */
170static int j_compilesub(lua_State *L)
171{
172 Closure *cl = check_LCL(L);
173 int stoponerror = lua_toboolean(L, 2); /* Stop on first error? */
174 lua_settop(L, 2);
175 return compstatus(L, rec_compile(L, cl->l.p, cl->l.env, stoponerror));
176}
177
178/* jit.* functions. */
179static const luaL_Reg jitlib[] = {
180 { "on", j_on },
181 { "off", j_off },
182 { "debug", j_debug },
183 { "compile", j_compile },
184 { "compilesub", j_compilesub },
185 /* j_attach is added below. */
186 { NULL, NULL }
187};
188
189/* ------------------------------------------------------------------------ */
190
191/* Get the compiler pipeline table from an upvalue (j_attach, j_frontend). */
192#define COMPIPE lua_upvalueindex(1)
193
194/* Attach/detach handler to/from compiler pipeline. */
195static int j_attach(lua_State *L)
196{
197 int pipesz;
198 luaL_checktype(L, 1, LUA_TFUNCTION);
199 pipesz = lua_objlen(L, COMPIPE);
200 if (lua_isnoneornil(L, 2)) { /* Detach if no priority given. */
201 int i;
202 for (i = 1; i <= pipesz; i += 2) {
203 lua_rawgeti(L, COMPIPE, i);
204 if (lua_rawequal(L, 1, -1)) { /* Found: delete from pipeline. */
205 for (; i+2 <= pipesz; i++) { /* Shift down. */
206 lua_rawgeti(L, COMPIPE, i+2);
207 lua_rawseti(L, COMPIPE, i);
208 }
209 /* Clear last two elements. */
210 lua_pushnil(L); lua_rawseti(L, COMPIPE, i);
211 lua_pushnil(L); lua_rawseti(L, COMPIPE, i+1);
212 return 0;
213 }
214 lua_pop(L, 1);
215 }
216 return 0; /* Not found: ignore detach request. */
217 } else { /* Attach if priority given. */
218 int prio = luaL_checkint(L, 2);
219 int pos, i;
220 for (pos = 2; pos <= pipesz; pos += 2) {
221 lua_rawgeti(L, COMPIPE, pos);
222 if (prio > (int)lua_tointeger(L, -1)) break; /* Insertion point found. */
223 lua_pop(L, 1);
224 }
225 for (i = pipesz+2; i > pos; i--) { /* Shift up. */
226 lua_rawgeti(L, COMPIPE, i-2);
227 lua_rawseti(L, COMPIPE, i);
228 }
229 /* Set handler and priority. */
230 lua_pushvalue(L, 1); lua_rawseti(L, COMPIPE, i-1);
231 lua_pushvalue(L, 2); lua_rawseti(L, COMPIPE, i);
232 return 0;
233 }
234}
235
236/* Compiler frontend. Runs in the compiler thread. */
237/* First and only arg is the compiler state table. */
238static int j_frontend(lua_State *L)
239{
240 int status = JIT_S_OK;
241 int pos;
242 /* Loop through all handlers in the compiler pipeline. */
243 for (pos = 1; ; pos += 2) {
244 if (status != JIT_S_OK) { /* Pending failure? */
245 int prio;
246 lua_rawgeti(L, COMPIPE, pos+1); /* Must check for odd/even priority. */
247 if (lua_isnil(L, -1)) break; /* End of pipeline. */
248 prio = (int)lua_tointeger(L, -1);
249 lua_pop(L, 1);
250 if ((prio & 1) == 0) continue; /* Skip handlers with even priority. */
251 }
252 /* Call handler with compiler state table and optional failure status. */
253 lua_rawgeti(L, COMPIPE, pos);
254 if (lua_isnil(L, -1)) break; /* End of pipeline. */
255 lua_pushvalue(L, 1);
256 if (status != JIT_S_OK)
257 lua_pushinteger(L, status);
258 lua_call(L, status ? 2 : 1, 1);
259 if (!lua_isnil(L, -1)) /* Remember failure status. */
260 status = (int)lua_tointeger(L, -1);
261 lua_pop(L, 1);
262 }
263 lua_pushinteger(L, status);
264 return 1;
265}
266
267/* Compiler frontend wrapper. */
268static int frontwrap(lua_State *L, Table *st)
269{
270 jit_State *J = G(L)->jit_state;
271 lua_State *JL;
272 int status;
273
274 /* Allocate compiler thread on demand. */
275 if (J->L == NULL) {
276 if (!lua_checkstack(L, 3)) return JIT_S_COMPILER_ERROR;
277 sethvalue(L, L->top++, st); /* Prevent GC of state table. */
278 lua_pushlightuserdata(L, (void *)&regkey_comthread);
279 /* Cannot use C stack, since it's deallocated early in Coco. */
280 /* But we don't need one -- the compiler thread never yields, anyway. */
281 J->L = lua_newthread(L);
282 lua_rawset(L, LUA_REGISTRYINDEX);
283 L->top--; /* Remove state table from this stack. */
284 }
285 JL = J->L;
286
287 /* Initialize compiler thread stack with frontend and state table. */
288 lua_settop(JL, 0);
289 lua_pushlightuserdata(JL, (void *)&regkey_frontend);
290 lua_rawget(JL, LUA_REGISTRYINDEX);
291 sethvalue(JL, JL->top, st);
292 JL->top++;
293
294 /* Start the frontend by resuming the compiler thread. */
295 if (lua_resume(JL, 1) != 0) { /* Failed? */
296 /* Note: LUA_YIELD is treated like any other error. */
297 J->L = NULL; /* Get a new thread next time. */
298 fprintf(stderr, "[LuaJIT frontend failed: %s]\n",
299 lua_isstring(JL, -1) ? lua_tostring(JL, -1) : "(unknown error)");
300 return JIT_S_COMPILER_ERROR;
301 }
302
303 /* Get status from terminated thread. */
304 status = (int)lua_tointeger(JL, -1);
305 lua_settop(JL, 0); /* Help the GC. */
306 return status;
307}
308
309/* Create the compiler pipeline and register it. */
310static void makepipeline(lua_State *L)
311{
312 lua_createtable(L, 20, 0); /* 10 handlers+priorities should be enough. */
313 lua_pushcfunction(L, luaJIT_backend);
314 lua_rawseti(L, -2, 1);
315 lua_pushinteger(L, 0); /* Fill in the backend at prio 0. */
316 lua_rawseti(L, -2, 2);
317
318 /* Store the compiler frontend in the registry. */
319 lua_pushlightuserdata(L, (void *)&regkey_frontend);
320 lua_pushvalue(L, -2); /* Pipeline table as upvalue. */
321 lua_pushcclosure(L, j_frontend, 1);
322 lua_rawset(L, LUA_REGISTRYINDEX);
323
324 /* Register the frontend wrapper. */
325 G(L)->jit_state->frontwrap = frontwrap;
326
327 /* Add jit.attach with the pipeline table as upvalue. */
328 lua_pushcclosure(L, j_attach, 1);
329 lua_setfield(L, -2, "attach"); /* "jit" table must be below. */
330}
331
332/* ------------------------------------------------------------------------ */
333
334/* Calculate total mcode size without mfm and only for active mcode blocks. */
335static size_t mcodesize(Proto *pt)
336{
337 jit_MCTrailer tr;
338 size_t sz = 0;
339 tr.mcode = (char *)pt->jit_mcode;
340 tr.sz = pt->jit_szmcode;
341 do {
342 jit_Mfm *mfm = JIT_MCMFM(tr.mcode, tr.sz);
343 if (sz != 0 && jit_mfm_ismain(mfm)) break; /* Stop at old main mfm. */
344 while (*mfm != JIT_MFM_STOP) mfm--; /* Search for end of mcode. */
345 sz += (char *)mfm-(char *)tr.mcode; /* Add size of mcode without mfm. */
346 memcpy((void *)&tr, JIT_MCTRAILER(tr.mcode, tr.sz), sizeof(jit_MCTrailer));
347 } while (tr.mcode != NULL);
348 return sz;
349}
350
351#define setintfield(name, i) \
352 do { lua_pushinteger(L, i); lua_setfield(L, -2, name); } while (0)
353
354/* local stats = jit.util.stats(func) */
355static int ju_stats(lua_State *L)
356{
357 if (!(L->top > L->base))
358 luaL_argerror(L, 1, "Lua function expected");
359 if (isLfunction(L->base)) {
360 Proto *pt = clvalue(L->base)->l.p;
361 lua_createtable(L, 0, 11);
362 setintfield("status", pt->jit_status);
363 setintfield("stackslots", pt->maxstacksize);
364 setintfield("params", pt->numparams);
365 setintfield("bytecodes", pt->sizecode);
366 setintfield("consts", pt->sizek);
367 setintfield("upvalues", pt->nups);
368 setintfield("subs", pt->sizep);
369 lua_pushboolean(L, pt->is_vararg);
370 lua_setfield(L, -2, "isvararg");
371 lua_getfenv(L, 1);
372 lua_setfield(L, -2, "env");
373 if (pt->jit_szmcode != 0) {
374 setintfield("mcodesize", (int)mcodesize(pt));
375 lua_pushnumber(L, (lua_Number)(size_t)pt->jit_mcode);
376 lua_setfield(L, -2, "mcodeaddr");
377 }
378 return 1;
379 } else {
380 return 0; /* Don't throw an error like the other util functions. */
381 }
382}
383
384/* local op, a, b, c, test = jit.util.bytecode(func, pc) */
385static int ju_bytecode(lua_State *L)
386{
387 Proto *pt = check_LCL(L)->l.p;
388 int pc = luaL_checkint(L, 2);
389 if (pc >= 1 && pc <= pt->sizecode) {
390 Instruction ins = pt->code[pc-1];
391 OpCode op = GET_OPCODE(ins);
392 if (pc > 1 && (((int)OP_SETLIST) << POS_OP) ==
393 (pt->code[pc-2] & (MASK1(SIZE_OP,POS_OP) | MASK1(SIZE_C,POS_C)))) {
394 lua_pushstring(L, luaP_opnames[OP_SETLIST]);
395 lua_pushnumber(L, (lua_Number)ins); /* Fake extended op. */
396 return 1;
397 }
398 if (op >= NUM_OPCODES) return 0; /* Just in case. */
399 lua_pushstring(L, luaP_opnames[op]);
400 lua_pushinteger(L, GETARG_A(ins));
401 switch (getOpMode(op)) {
402 case iABC: {
403 int b = GETARG_B(ins), c = GETARG_C(ins);
404 switch (getBMode(op)) {
405 case OpArgN: lua_pushnil(L); break;
406 case OpArgK: if (ISK(b)) b = -1-INDEXK(b);
407 case OpArgR: case OpArgU: lua_pushinteger(L, b); break;
408 }
409 switch (getCMode(op)) {
410 case OpArgN: lua_pushnil(L); break;
411 case OpArgK: if (ISK(c)) c = -1-INDEXK(c);
412 case OpArgR: case OpArgU: lua_pushinteger(L, c); break;
413 }
414 lua_pushboolean(L, testTMode(op));
415 return 5;
416 }
417 case iABx: {
418 int bx = GETARG_Bx(ins);
419 lua_pushinteger(L, getBMode(op) == OpArgK ? -1-bx : bx);
420 return 3;
421 }
422 case iAsBx:
423 lua_pushinteger(L, GETARG_sBx(ins));
424 return 3;
425 }
426 }
427 return 0;
428}
429
430/* local const, ok = jit.util.const(func, idx) */
431static int ju_const(lua_State *L)
432{
433 Proto *pt = check_LCL(L)->l.p;
434 int idx = luaL_checkint(L, 2);
435 if (idx < 0) idx = -idx; /* Handle both positive and negative indices. */
436 if (idx >= 1 && idx <= pt->sizek) {
437 setobj2s(L, L->top-1, &pt->k[idx-1]);
438 lua_pushboolean(L, 1);
439 return 2;
440 }
441 lua_pushnil(L);
442 lua_pushboolean(L, 0);
443 return 2;
444}
445
446/* local upvalue, ok = jit.util.upvalue(func, idx) */
447static int ju_upvalue(lua_State *L)
448{
449 Closure *cl = check_LCL(L);
450 Proto *pt = cl->l.p;
451 int idx = luaL_checkint(L, 2);
452 if (idx >= 0 && idx < pt->nups) {
453 setobj2s(L, L->top-1, cl->l.upvals[idx]->v);
454 lua_pushboolean(L, 1);
455 return 2;
456 }
457 lua_pushnil(L);
458 lua_pushboolean(L, 0);
459 return 2;
460}
461
462/* local nup = jit.util.closurenup(func, idx) */
463static int ju_closurenup(lua_State *L)
464{
465 Closure *cl = check_LCL(L);
466 Proto *pt = cl->l.p;
467 int idx = luaL_checkint(L, 2);
468 if (idx >= 0 && idx < pt->sizep) {
469 lua_pushinteger(L, pt->p[idx]->nups);
470 return 1;
471 }
472 return 0;
473}
474
475/* for tag, mark in mfmiter do ... end. */
476static int ju_mfmiter(lua_State *L)
477{
478 jit_Mfm *mfm = (jit_Mfm *)lua_touserdata(L, lua_upvalueindex(1));
479 int m = *mfm--;
480 switch (m) {
481 case JIT_MFM_STOP: return 0;
482 case JIT_MFM_COMBINE: lua_pushliteral(L, "COMBINE"); lua_pushnil(L); break;
483 case JIT_MFM_DEAD: lua_pushliteral(L, "DEAD"); lua_pushnil(L); break;
484 default:
485 lua_pushinteger(L, m & JIT_MFM_MASK);
486 lua_pushboolean(L, m & JIT_MFM_MARK);
487 break;
488 }
489 lua_pushlightuserdata(L, (void *)mfm);
490 lua_replace(L, lua_upvalueindex(1));
491 return 2;
492}
493
494/* local addr, mcode, mfmiter = jit.util.mcode(func, block) */
495static int ju_mcode(lua_State *L)
496{
497 Proto *pt = check_LCL(L)->l.p;
498 if (pt->jit_szmcode == 0) { /* Not compiled (yet): return nil, status. */
499 lua_pushnil(L);
500 lua_pushinteger(L, pt->jit_status);
501 return 2;
502 } else {
503 jit_Mfm *mfm;
504 jit_MCTrailer tr;
505 int block = luaL_checkint(L, 2);
506 tr.mcode = (char *)pt->jit_mcode;
507 tr.sz = pt->jit_szmcode;
508 while (--block > 0) {
509 void *trp = JIT_MCTRAILER(tr.mcode, tr.sz);
510 memcpy((void *)&tr, trp, sizeof(jit_MCTrailer));
511 if (tr.sz == 0) return 0;
512 }
513 mfm = JIT_MCMFM(tr.mcode, tr.sz);
514 while (*mfm != JIT_MFM_STOP) mfm--; /* Search for end of mcode. */
515 lua_pushnumber(L, (lua_Number)(size_t)tr.mcode);
516 lua_pushlstring(L, (const char *)tr.mcode, (char *)mfm-(char *)tr.mcode);
517 lua_pushlightuserdata(L, (void *)JIT_MCMFM(tr.mcode, tr.sz));
518 lua_pushvalue(L, 1); /* Must hold onto function to avoid GC. */
519 lua_pushcclosure(L, ju_mfmiter, 2);
520 return 3;
521 }
522}
523
524/* local addr [, mcode] = jit.util.jsubmcode([idx]) */
525static int ju_jsubmcode(lua_State *L)
526{
527 jit_State *J = G(L)->jit_state;
528 if (lua_isnoneornil(L, 1)) {
529 lua_pushnumber(L, (lua_Number)(size_t)J->jsubmcode);
530 lua_pushlstring(L, (const char *)J->jsubmcode, J->szjsubmcode);
531 return 2;
532 } else {
533 int idx = luaL_checkint(L, 1);
534 if (idx >= 0 && idx < J->numjsub) {
535 lua_pushnumber(L, (lua_Number)(size_t)J->jsub[idx]);
536 return 1;
537 }
538 return 0;
539 }
540}
541
542/* FOR INTERNAL DEBUGGING USE ONLY: local addr = jit.util.stackptr() */
543static int ju_stackptr(lua_State *L)
544{
545 jit_State *J = G(L)->jit_state;
546 size_t addr = cast(size_t (*)(void), J->jsub[0])(); /* JSUB_STACKPTR == 0! */
547 lua_pushnumber(L, (lua_Number)addr);
548 return 1;
549}
550
551/* jit.util.* functions. */
552static const luaL_Reg jitutillib[] = {
553 {"stats", ju_stats },
554 {"bytecode", ju_bytecode },
555 {"const", ju_const },
556 {"upvalue", ju_upvalue },
557 {"closurenup", ju_closurenup },
558 {"mcode", ju_mcode },
559 {"jsubmcode", ju_jsubmcode },
560 {"stackptr", ju_stackptr },
561 { NULL, NULL }
562};
563
564/* Make hint name to hint number map. */
565static void makehints(lua_State *L, const char *const *t, int tmax,
566 const char *name)
567{
568 int i;
569 lua_createtable(L, 0, tmax);
570 for (i = 1; i < tmax; i++) {
571 lua_pushinteger(L, JIT_H2NUM(i));
572 lua_setfield(L, -2, t[i-1]);
573 }
574 lua_setfield(L, -2, name);
575}
576
577/* CHECK: must match with ljit.h (grep "ORDER JIT_S"). */
578static const char *const status_list[] = {
579 "OK",
580 "NONE",
581 "OFF",
582 "ENGINE_OFF",
583 "DELAYED",
584 "TOOLARGE",
585 "COMPILER_ERROR",
586 "DASM_ERROR"
587};
588
589/* Make bidirectional status name to status number map. */
590static void makestatus(lua_State *L, const char *name)
591{
592 int i;
593 lua_createtable(L, JIT_S_MAX-1, JIT_S_MAX+1); /* Codes are not 1-based. */
594 for (i = 0; i < JIT_S_MAX; i++) {
595 lua_pushstring(L, status_list[i]);
596 lua_pushinteger(L, i);
597 lua_pushvalue(L, -2);
598 lua_rawseti(L, -4, i);
599 lua_rawset(L, -3);
600 }
601 lua_setfield(L, -2, name);
602}
603
604/* ------------------------------------------------------------------------ */
605
606/*
607** Open JIT library
608*/
609LUALIB_API int luaopen_jit(lua_State *L)
610{
611 /* Add the core JIT library. */
612 luaL_register(L, LUA_JITLIBNAME, jitlib);
613 lua_pushliteral(L, LUAJIT_VERSION);
614 lua_setfield(L, -2, "version");
615 setintfield("version_num", LUAJIT_VERSION_NUM);
616 lua_pushstring(L, luaJIT_arch);
617 lua_setfield(L, -2, "arch");
618 makepipeline(L);
619
620 /* Add the utility JIT library. */
621 luaL_register(L, LUA_JITLIBNAME ".util", jitutillib);
622 makestatus(L, "status");
623 makehints(L, hints_H, JIT_H_MAX, "hints");
624 makehints(L, hints_FH, JIT_FH_MAX, "fhints");
625 lua_pop(L, 1);
626
627 /* Everything ok, so turn the JIT engine on. Vroooom! */
628 if (luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|LUAJIT_MODE_ON) <= 0) {
629 /* Ouch. Someone screwed up DynASM or the JSUBs. Probably me. */
630 /* But if you get 999999999, look at jit_consistency_check(). */
631 return luaL_error(L, "JIT engine init failed (%d)",
632 G(L)->jit_state->dasmstatus);
633 }
634
635 return 1;
636}
637