aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/luajit-2.0/src/lib_jit.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/luajit-2.0/src/lib_jit.c')
-rw-r--r--libraries/luajit-2.0/src/lib_jit.c659
1 files changed, 659 insertions, 0 deletions
diff --git a/libraries/luajit-2.0/src/lib_jit.c b/libraries/luajit-2.0/src/lib_jit.c
new file mode 100644
index 0000000..8cb511c
--- /dev/null
+++ b/libraries/luajit-2.0/src/lib_jit.c
@@ -0,0 +1,659 @@
1/*
2** JIT library.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lib_jit_c
7#define LUA_LIB
8
9#include "lua.h"
10#include "lauxlib.h"
11#include "lualib.h"
12
13#include "lj_arch.h"
14#include "lj_obj.h"
15#include "lj_err.h"
16#include "lj_debug.h"
17#include "lj_str.h"
18#include "lj_tab.h"
19#include "lj_bc.h"
20#if LJ_HASJIT
21#include "lj_ir.h"
22#include "lj_jit.h"
23#include "lj_ircall.h"
24#include "lj_iropt.h"
25#include "lj_target.h"
26#endif
27#include "lj_dispatch.h"
28#include "lj_vm.h"
29#include "lj_vmevent.h"
30#include "lj_lib.h"
31
32#include "luajit.h"
33
34/* -- jit.* functions ----------------------------------------------------- */
35
36#define LJLIB_MODULE_jit
37
38static int setjitmode(lua_State *L, int mode)
39{
40 int idx = 0;
41 if (L->base == L->top || tvisnil(L->base)) { /* jit.on/off/flush([nil]) */
42 mode |= LUAJIT_MODE_ENGINE;
43 } else {
44 /* jit.on/off/flush(func|proto, nil|true|false) */
45 if (tvisfunc(L->base) || tvisproto(L->base))
46 idx = 1;
47 else if (!tvistrue(L->base)) /* jit.on/off/flush(true, nil|true|false) */
48 goto err;
49 if (L->base+1 < L->top && tvisbool(L->base+1))
50 mode |= boolV(L->base+1) ? LUAJIT_MODE_ALLFUNC : LUAJIT_MODE_ALLSUBFUNC;
51 else
52 mode |= LUAJIT_MODE_FUNC;
53 }
54 if (luaJIT_setmode(L, idx, mode) != 1) {
55 if ((mode & LUAJIT_MODE_MASK) == LUAJIT_MODE_ENGINE)
56 lj_err_caller(L, LJ_ERR_NOJIT);
57 err:
58 lj_err_argt(L, 1, LUA_TFUNCTION);
59 }
60 return 0;
61}
62
63LJLIB_CF(jit_on)
64{
65 return setjitmode(L, LUAJIT_MODE_ON);
66}
67
68LJLIB_CF(jit_off)
69{
70 return setjitmode(L, LUAJIT_MODE_OFF);
71}
72
73LJLIB_CF(jit_flush)
74{
75#if LJ_HASJIT
76 if (L->base < L->top && !tvisnil(L->base)) {
77 int traceno = lj_lib_checkint(L, 1);
78 luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE);
79 return 0;
80 }
81#endif
82 return setjitmode(L, LUAJIT_MODE_FLUSH);
83}
84
85#if LJ_HASJIT
86/* Push a string for every flag bit that is set. */
87static void flagbits_to_strings(lua_State *L, uint32_t flags, uint32_t base,
88 const char *str)
89{
90 for (; *str; base <<= 1, str += 1+*str)
91 if (flags & base)
92 setstrV(L, L->top++, lj_str_new(L, str+1, *(uint8_t *)str));
93}
94#endif
95
96LJLIB_CF(jit_status)
97{
98#if LJ_HASJIT
99 jit_State *J = L2J(L);
100 L->top = L->base;
101 setboolV(L->top++, (J->flags & JIT_F_ON) ? 1 : 0);
102 flagbits_to_strings(L, J->flags, JIT_F_CPU_FIRST, JIT_F_CPUSTRING);
103 flagbits_to_strings(L, J->flags, JIT_F_OPT_FIRST, JIT_F_OPTSTRING);
104 return (int)(L->top - L->base);
105#else
106 setboolV(L->top++, 0);
107 return 1;
108#endif
109}
110
111LJLIB_CF(jit_attach)
112{
113#ifdef LUAJIT_DISABLE_VMEVENT
114 luaL_error(L, "vmevent API disabled");
115#else
116 GCfunc *fn = lj_lib_checkfunc(L, 1);
117 GCstr *s = lj_lib_optstr(L, 2);
118 luaL_findtable(L, LUA_REGISTRYINDEX, LJ_VMEVENTS_REGKEY, LJ_VMEVENTS_HSIZE);
119 if (s) { /* Attach to given event. */
120 const uint8_t *p = (const uint8_t *)strdata(s);
121 uint32_t h = s->len;
122 while (*p) h = h ^ (lj_rol(h, 6) + *p++);
123 lua_pushvalue(L, 1);
124 lua_rawseti(L, -2, VMEVENT_HASHIDX(h));
125 G(L)->vmevmask = VMEVENT_NOCACHE; /* Invalidate cache. */
126 } else { /* Detach if no event given. */
127 setnilV(L->top++);
128 while (lua_next(L, -2)) {
129 L->top--;
130 if (tvisfunc(L->top) && funcV(L->top) == fn) {
131 setnilV(lj_tab_set(L, tabV(L->top-2), L->top-1));
132 }
133 }
134 }
135#endif
136 return 0;
137}
138
139LJLIB_PUSH(top-5) LJLIB_SET(os)
140LJLIB_PUSH(top-4) LJLIB_SET(arch)
141LJLIB_PUSH(top-3) LJLIB_SET(version_num)
142LJLIB_PUSH(top-2) LJLIB_SET(version)
143
144#include "lj_libdef.h"
145
146/* -- jit.util.* functions ------------------------------------------------ */
147
148#define LJLIB_MODULE_jit_util
149
150/* -- Reflection API for Lua functions ------------------------------------ */
151
152/* Return prototype of first argument (Lua function or prototype object) */
153static GCproto *check_Lproto(lua_State *L, int nolua)
154{
155 TValue *o = L->base;
156 if (L->top > o) {
157 if (tvisproto(o)) {
158 return protoV(o);
159 } else if (tvisfunc(o)) {
160 if (isluafunc(funcV(o)))
161 return funcproto(funcV(o));
162 else if (nolua)
163 return NULL;
164 }
165 }
166 lj_err_argt(L, 1, LUA_TFUNCTION);
167 return NULL; /* unreachable */
168}
169
170static void setintfield(lua_State *L, GCtab *t, const char *name, int32_t val)
171{
172 setintV(lj_tab_setstr(L, t, lj_str_newz(L, name)), val);
173}
174
175/* local info = jit.util.funcinfo(func [,pc]) */
176LJLIB_CF(jit_util_funcinfo)
177{
178 GCproto *pt = check_Lproto(L, 1);
179 if (pt) {
180 BCPos pc = (BCPos)lj_lib_optint(L, 2, 0);
181 GCtab *t;
182 lua_createtable(L, 0, 16); /* Increment hash size if fields are added. */
183 t = tabV(L->top-1);
184 setintfield(L, t, "linedefined", pt->firstline);
185 setintfield(L, t, "lastlinedefined", pt->firstline + pt->numline);
186 setintfield(L, t, "stackslots", pt->framesize);
187 setintfield(L, t, "params", pt->numparams);
188 setintfield(L, t, "bytecodes", (int32_t)pt->sizebc);
189 setintfield(L, t, "gcconsts", (int32_t)pt->sizekgc);
190 setintfield(L, t, "nconsts", (int32_t)pt->sizekn);
191 setintfield(L, t, "upvalues", (int32_t)pt->sizeuv);
192 if (pc < pt->sizebc)
193 setintfield(L, t, "currentline", lj_debug_line(pt, pc));
194 lua_pushboolean(L, (pt->flags & PROTO_VARARG));
195 lua_setfield(L, -2, "isvararg");
196 lua_pushboolean(L, (pt->flags & PROTO_CHILD));
197 lua_setfield(L, -2, "children");
198 setstrV(L, L->top++, proto_chunkname(pt));
199 lua_setfield(L, -2, "source");
200 lj_debug_pushloc(L, pt, pc);
201 lua_setfield(L, -2, "loc");
202 } else {
203 GCfunc *fn = funcV(L->base);
204 GCtab *t;
205 lua_createtable(L, 0, 4); /* Increment hash size if fields are added. */
206 t = tabV(L->top-1);
207 if (!iscfunc(fn))
208 setintfield(L, t, "ffid", fn->c.ffid);
209 setintptrV(lj_tab_setstr(L, t, lj_str_newlit(L, "addr")),
210 (intptr_t)(void *)fn->c.f);
211 setintfield(L, t, "upvalues", fn->c.nupvalues);
212 }
213 return 1;
214}
215
216/* local ins, m = jit.util.funcbc(func, pc) */
217LJLIB_CF(jit_util_funcbc)
218{
219 GCproto *pt = check_Lproto(L, 0);
220 BCPos pc = (BCPos)lj_lib_checkint(L, 2);
221 if (pc < pt->sizebc) {
222 BCIns ins = proto_bc(pt)[pc];
223 BCOp op = bc_op(ins);
224 lua_assert(op < BC__MAX);
225 setintV(L->top, ins);
226 setintV(L->top+1, lj_bc_mode[op]);
227 L->top += 2;
228 return 2;
229 }
230 return 0;
231}
232
233/* local k = jit.util.funck(func, idx) */
234LJLIB_CF(jit_util_funck)
235{
236 GCproto *pt = check_Lproto(L, 0);
237 ptrdiff_t idx = (ptrdiff_t)lj_lib_checkint(L, 2);
238 if (idx >= 0) {
239 if (idx < (ptrdiff_t)pt->sizekn) {
240 copyTV(L, L->top-1, proto_knumtv(pt, idx));
241 return 1;
242 }
243 } else {
244 if (~idx < (ptrdiff_t)pt->sizekgc) {
245 GCobj *gc = proto_kgc(pt, idx);
246 setgcV(L, L->top-1, gc, ~gc->gch.gct);
247 return 1;
248 }
249 }
250 return 0;
251}
252
253/* local name = jit.util.funcuvname(func, idx) */
254LJLIB_CF(jit_util_funcuvname)
255{
256 GCproto *pt = check_Lproto(L, 0);
257 uint32_t idx = (uint32_t)lj_lib_checkint(L, 2);
258 if (idx < pt->sizeuv) {
259 setstrV(L, L->top-1, lj_str_newz(L, lj_debug_uvname(pt, idx)));
260 return 1;
261 }
262 return 0;
263}
264
265/* -- Reflection API for traces ------------------------------------------- */
266
267#if LJ_HASJIT
268
269/* Check trace argument. Must not throw for non-existent trace numbers. */
270static GCtrace *jit_checktrace(lua_State *L)
271{
272 TraceNo tr = (TraceNo)lj_lib_checkint(L, 1);
273 jit_State *J = L2J(L);
274 if (tr > 0 && tr < J->sizetrace)
275 return traceref(J, tr);
276 return NULL;
277}
278
279/* Names of link types. ORDER LJ_TRLINK */
280static const char *const jit_trlinkname[] = {
281 "none", "root", "loop", "tail-recursion", "up-recursion", "down-recursion",
282 "interpreter", "return"
283};
284
285/* local info = jit.util.traceinfo(tr) */
286LJLIB_CF(jit_util_traceinfo)
287{
288 GCtrace *T = jit_checktrace(L);
289 if (T) {
290 GCtab *t;
291 lua_createtable(L, 0, 8); /* Increment hash size if fields are added. */
292 t = tabV(L->top-1);
293 setintfield(L, t, "nins", (int32_t)T->nins - REF_BIAS - 1);
294 setintfield(L, t, "nk", REF_BIAS - (int32_t)T->nk);
295 setintfield(L, t, "link", T->link);
296 setintfield(L, t, "nexit", T->nsnap);
297 setstrV(L, L->top++, lj_str_newz(L, jit_trlinkname[T->linktype]));
298 lua_setfield(L, -2, "linktype");
299 /* There are many more fields. Add them only when needed. */
300 return 1;
301 }
302 return 0;
303}
304
305/* local m, ot, op1, op2, prev = jit.util.traceir(tr, idx) */
306LJLIB_CF(jit_util_traceir)
307{
308 GCtrace *T = jit_checktrace(L);
309 IRRef ref = (IRRef)lj_lib_checkint(L, 2) + REF_BIAS;
310 if (T && ref >= REF_BIAS && ref < T->nins) {
311 IRIns *ir = &T->ir[ref];
312 int32_t m = lj_ir_mode[ir->o];
313 setintV(L->top-2, m);
314 setintV(L->top-1, ir->ot);
315 setintV(L->top++, (int32_t)ir->op1 - (irm_op1(m)==IRMref ? REF_BIAS : 0));
316 setintV(L->top++, (int32_t)ir->op2 - (irm_op2(m)==IRMref ? REF_BIAS : 0));
317 setintV(L->top++, ir->prev);
318 return 5;
319 }
320 return 0;
321}
322
323/* local k, t [, slot] = jit.util.tracek(tr, idx) */
324LJLIB_CF(jit_util_tracek)
325{
326 GCtrace *T = jit_checktrace(L);
327 IRRef ref = (IRRef)lj_lib_checkint(L, 2) + REF_BIAS;
328 if (T && ref >= T->nk && ref < REF_BIAS) {
329 IRIns *ir = &T->ir[ref];
330 int32_t slot = -1;
331 if (ir->o == IR_KSLOT) {
332 slot = ir->op2;
333 ir = &T->ir[ir->op1];
334 }
335 lj_ir_kvalue(L, L->top-2, ir);
336 setintV(L->top-1, (int32_t)irt_type(ir->t));
337 if (slot == -1)
338 return 2;
339 setintV(L->top++, slot);
340 return 3;
341 }
342 return 0;
343}
344
345/* local snap = jit.util.tracesnap(tr, sn) */
346LJLIB_CF(jit_util_tracesnap)
347{
348 GCtrace *T = jit_checktrace(L);
349 SnapNo sn = (SnapNo)lj_lib_checkint(L, 2);
350 if (T && sn < T->nsnap) {
351 SnapShot *snap = &T->snap[sn];
352 SnapEntry *map = &T->snapmap[snap->mapofs];
353 MSize n, nent = snap->nent;
354 GCtab *t;
355 lua_createtable(L, nent+2, 0);
356 t = tabV(L->top-1);
357 setintV(lj_tab_setint(L, t, 0), (int32_t)snap->ref - REF_BIAS);
358 setintV(lj_tab_setint(L, t, 1), (int32_t)snap->nslots);
359 for (n = 0; n < nent; n++)
360 setintV(lj_tab_setint(L, t, (int32_t)(n+2)), (int32_t)map[n]);
361 setintV(lj_tab_setint(L, t, (int32_t)(nent+2)), (int32_t)SNAP(255, 0, 0));
362 return 1;
363 }
364 return 0;
365}
366
367/* local mcode, addr, loop = jit.util.tracemc(tr) */
368LJLIB_CF(jit_util_tracemc)
369{
370 GCtrace *T = jit_checktrace(L);
371 if (T && T->mcode != NULL) {
372 setstrV(L, L->top-1, lj_str_new(L, (const char *)T->mcode, T->szmcode));
373 setintptrV(L->top++, (intptr_t)(void *)T->mcode);
374 setintV(L->top++, T->mcloop);
375 return 3;
376 }
377 return 0;
378}
379
380/* local addr = jit.util.traceexitstub([tr,] exitno) */
381LJLIB_CF(jit_util_traceexitstub)
382{
383#ifdef EXITSTUBS_PER_GROUP
384 ExitNo exitno = (ExitNo)lj_lib_checkint(L, 1);
385 jit_State *J = L2J(L);
386 if (exitno < EXITSTUBS_PER_GROUP*LJ_MAX_EXITSTUBGR) {
387 setintptrV(L->top-1, (intptr_t)(void *)exitstub_addr(J, exitno));
388 return 1;
389 }
390#else
391 if (L->top > L->base+1) { /* Don't throw for one-argument variant. */
392 GCtrace *T = jit_checktrace(L);
393 ExitNo exitno = (ExitNo)lj_lib_checkint(L, 2);
394 ExitNo maxexit = T->root ? T->nsnap+1 : T->nsnap;
395 if (T && T->mcode != NULL && exitno < maxexit) {
396 setintptrV(L->top-1, (intptr_t)(void *)exitstub_trace_addr(T, exitno));
397 return 1;
398 }
399 }
400#endif
401 return 0;
402}
403
404/* local addr = jit.util.ircalladdr(idx) */
405LJLIB_CF(jit_util_ircalladdr)
406{
407 uint32_t idx = (uint32_t)lj_lib_checkint(L, 1);
408 if (idx < IRCALL__MAX) {
409 setintptrV(L->top-1, (intptr_t)(void *)lj_ir_callinfo[idx].func);
410 return 1;
411 }
412 return 0;
413}
414
415#else
416
417static int trace_nojit(lua_State *L)
418{
419 UNUSED(L);
420 return 0;
421}
422#define lj_cf_jit_util_traceinfo trace_nojit
423#define lj_cf_jit_util_traceir trace_nojit
424#define lj_cf_jit_util_tracek trace_nojit
425#define lj_cf_jit_util_tracesnap trace_nojit
426#define lj_cf_jit_util_tracemc trace_nojit
427#define lj_cf_jit_util_traceexitstub trace_nojit
428#define lj_cf_jit_util_ircalladdr trace_nojit
429
430#endif
431
432#include "lj_libdef.h"
433
434/* -- jit.opt module ------------------------------------------------------ */
435
436#define LJLIB_MODULE_jit_opt
437
438#if LJ_HASJIT
439/* Parse optimization level. */
440static int jitopt_level(jit_State *J, const char *str)
441{
442 if (str[0] >= '0' && str[0] <= '9' && str[1] == '\0') {
443 uint32_t flags;
444 if (str[0] == '0') flags = JIT_F_OPT_0;
445 else if (str[0] == '1') flags = JIT_F_OPT_1;
446 else if (str[0] == '2') flags = JIT_F_OPT_2;
447 else flags = JIT_F_OPT_3;
448 J->flags = (J->flags & ~JIT_F_OPT_MASK) | flags;
449 return 1; /* Ok. */
450 }
451 return 0; /* No match. */
452}
453
454/* Parse optimization flag. */
455static int jitopt_flag(jit_State *J, const char *str)
456{
457 const char *lst = JIT_F_OPTSTRING;
458 uint32_t opt;
459 int set = 1;
460 if (str[0] == '+') {
461 str++;
462 } else if (str[0] == '-') {
463 str++;
464 set = 0;
465 } else if (str[0] == 'n' && str[1] == 'o') {
466 str += str[2] == '-' ? 3 : 2;
467 set = 0;
468 }
469 for (opt = JIT_F_OPT_FIRST; ; opt <<= 1) {
470 size_t len = *(const uint8_t *)lst;
471 if (len == 0)
472 break;
473 if (strncmp(str, lst+1, len) == 0 && str[len] == '\0') {
474 if (set) J->flags |= opt; else J->flags &= ~opt;
475 return 1; /* Ok. */
476 }
477 lst += 1+len;
478 }
479 return 0; /* No match. */
480}
481
482/* Parse optimization parameter. */
483static int jitopt_param(jit_State *J, const char *str)
484{
485 const char *lst = JIT_P_STRING;
486 int i;
487 for (i = 0; i < JIT_P__MAX; i++) {
488 size_t len = *(const uint8_t *)lst;
489 lua_assert(len != 0);
490 if (strncmp(str, lst+1, len) == 0 && str[len] == '=') {
491 int32_t n = 0;
492 const char *p = &str[len+1];
493 while (*p >= '0' && *p <= '9')
494 n = n*10 + (*p++ - '0');
495 if (*p) return 0; /* Malformed number. */
496 J->param[i] = n;
497 if (i == JIT_P_hotloop)
498 lj_dispatch_init_hotcount(J2G(J));
499 return 1; /* Ok. */
500 }
501 lst += 1+len;
502 }
503 return 0; /* No match. */
504}
505#endif
506
507/* jit.opt.start(flags...) */
508LJLIB_CF(jit_opt_start)
509{
510#if LJ_HASJIT
511 jit_State *J = L2J(L);
512 int nargs = (int)(L->top - L->base);
513 if (nargs == 0) {
514 J->flags = (J->flags & ~JIT_F_OPT_MASK) | JIT_F_OPT_DEFAULT;
515 } else {
516 int i;
517 for (i = 1; i <= nargs; i++) {
518 const char *str = strdata(lj_lib_checkstr(L, i));
519 if (!jitopt_level(J, str) &&
520 !jitopt_flag(J, str) &&
521 !jitopt_param(J, str))
522 lj_err_callerv(L, LJ_ERR_JITOPT, str);
523 }
524 }
525#else
526 lj_err_caller(L, LJ_ERR_NOJIT);
527#endif
528 return 0;
529}
530
531#include "lj_libdef.h"
532
533/* -- JIT compiler initialization ----------------------------------------- */
534
535#if LJ_HASJIT
536/* Default values for JIT parameters. */
537static const int32_t jit_param_default[JIT_P__MAX+1] = {
538#define JIT_PARAMINIT(len, name, value) (value),
539JIT_PARAMDEF(JIT_PARAMINIT)
540#undef JIT_PARAMINIT
541 0
542};
543#endif
544
545#if LJ_TARGET_ARM && LJ_TARGET_LINUX
546#include <sys/utsname.h>
547#endif
548
549/* Arch-dependent CPU detection. */
550static uint32_t jit_cpudetect(lua_State *L)
551{
552 uint32_t flags = 0;
553#if LJ_TARGET_X86ORX64
554 uint32_t vendor[4];
555 uint32_t features[4];
556 if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) {
557#if !LJ_HASJIT
558#define JIT_F_CMOV 1
559#define JIT_F_SSE2 2
560#endif
561 flags |= ((features[3] >> 15)&1) * JIT_F_CMOV;
562 flags |= ((features[3] >> 26)&1) * JIT_F_SSE2;
563#if LJ_HASJIT
564 flags |= ((features[2] >> 0)&1) * JIT_F_SSE3;
565 flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1;
566 if (vendor[2] == 0x6c65746e) { /* Intel. */
567 if ((features[0] & 0x0ff00f00) == 0x00000f00) /* P4. */
568 flags |= JIT_F_P4; /* Currently unused. */
569 else if ((features[0] & 0x0fff0ff0) == 0x000106c0) /* Atom. */
570 flags |= JIT_F_LEA_AGU;
571 } else if (vendor[2] == 0x444d4163) { /* AMD. */
572 uint32_t fam = (features[0] & 0x0ff00f00);
573 if (fam == 0x00000f00) /* K8. */
574 flags |= JIT_F_SPLIT_XMM;
575 if (fam >= 0x00000f00) /* K8, K10. */
576 flags |= JIT_F_PREFER_IMUL;
577 }
578#endif
579 }
580 /* Check for required instruction set support on x86 (unnecessary on x64). */
581#if LJ_TARGET_X86
582#if !defined(LUAJIT_CPU_NOCMOV)
583 if (!(flags & JIT_F_CMOV))
584 luaL_error(L, "Ancient CPU lacks CMOV support (recompile with -DLUAJIT_CPU_NOCMOV)");
585#endif
586#if defined(LUAJIT_CPU_SSE2)
587 if (!(flags & JIT_F_SSE2))
588 luaL_error(L, "CPU does not support SSE2 (recompile without -DLUAJIT_CPU_SSE2)");
589#endif
590#endif
591#elif LJ_TARGET_ARM
592#if LJ_HASJIT
593 /* Compile-time ARM CPU detection. */
594#if __ARM_ARCH_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__
595 flags |= JIT_F_ARMV6|JIT_F_ARMV6T2|JIT_F_ARMV7;
596#elif __ARM_ARCH_6T2__
597 flags |= JIT_F_ARMV6|JIT_F_ARMV6T2;
598#elif __ARM_ARCH_6__ || __ARM_ARCH_6J__ || __ARM_ARCH_6Z__ || __ARM_ARCH_6ZK__
599 flags |= JIT_F_ARMV6;
600#endif
601 /* Runtime ARM CPU detection. */
602#if LJ_TARGET_LINUX
603 if (!(flags & JIT_F_ARMV7)) {
604 struct utsname ut;
605 uname(&ut);
606 if (strncmp(ut.machine, "armv", 4) == 0) {
607 if (ut.machine[4] >= '7')
608 flags |= JIT_F_ARMV6|JIT_F_ARMV6T2|JIT_F_ARMV7;
609 else if (ut.machine[4] == '6')
610 flags |= JIT_F_ARMV6;
611 }
612 }
613#endif
614#endif
615#elif LJ_TARGET_PPC || LJ_TARGET_PPCSPE
616 /* Nothing to do. */
617#elif LJ_TARGET_MIPS
618 /* NYI */
619#else
620#error "Missing CPU detection for this architecture"
621#endif
622 UNUSED(L);
623 return flags;
624}
625
626/* Initialize JIT compiler. */
627static void jit_init(lua_State *L)
628{
629 uint32_t flags = jit_cpudetect(L);
630#if LJ_HASJIT
631 jit_State *J = L2J(L);
632#if LJ_TARGET_X86
633 /* Silently turn off the JIT compiler on CPUs without SSE2. */
634 if ((flags & JIT_F_SSE2))
635#endif
636 J->flags = flags | JIT_F_ON | JIT_F_OPT_DEFAULT;
637 memcpy(J->param, jit_param_default, sizeof(J->param));
638 lj_dispatch_update(G(L));
639#else
640 UNUSED(flags);
641#endif
642}
643
644LUALIB_API int luaopen_jit(lua_State *L)
645{
646 lua_pushliteral(L, LJ_OS_NAME);
647 lua_pushliteral(L, LJ_ARCH_NAME);
648 lua_pushinteger(L, LUAJIT_VERSION_NUM);
649 lua_pushliteral(L, LUAJIT_VERSION);
650 LJ_LIB_REG(L, LUA_JITLIBNAME, jit);
651#ifndef LUAJIT_DISABLE_JITUTIL
652 LJ_LIB_REG(L, "jit.util", jit_util);
653#endif
654 LJ_LIB_REG(L, "jit.opt", jit_opt);
655 L->top -= 2;
656 jit_init(L);
657 return 1;
658}
659