3 ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
27 #include "lj_ircall.h"
29 #include "lj_target.h"
32 #include "lj_dispatch.h"
34 #include "lj_vmevent.h"
39 /* -- jit.* functions ----------------------------------------------------- */
41 #define LJLIB_MODULE_jit
43 static int setjitmode(lua_State
*L
, int mode
)
46 if (L
->base
== L
->top
|| tvisnil(L
->base
)) { /* jit.on/off/flush([nil]) */
47 mode
|= LUAJIT_MODE_ENGINE
;
49 /* jit.on/off/flush(func|proto, nil|true|false) */
50 if (tvisfunc(L
->base
) || tvisproto(L
->base
))
52 else if (!tvistrue(L
->base
)) /* jit.on/off/flush(true, nil|true|false) */
54 if (L
->base
+1 < L
->top
&& tvisbool(L
->base
+1))
55 mode
|= boolV(L
->base
+1) ? LUAJIT_MODE_ALLFUNC
: LUAJIT_MODE_ALLSUBFUNC
;
57 mode
|= LUAJIT_MODE_FUNC
;
59 if (luaJIT_setmode(L
, idx
, mode
) != 1) {
60 if ((mode
& LUAJIT_MODE_MASK
) == LUAJIT_MODE_ENGINE
)
61 lj_err_caller(L
, LJ_ERR_NOJIT
);
63 lj_err_argt(L
, 1, LUA_TFUNCTION
);
70 return setjitmode(L
, LUAJIT_MODE_ON
);
75 return setjitmode(L
, LUAJIT_MODE_OFF
);
81 if (L
->base
< L
->top
&& tvisnumber(L
->base
)) {
82 int traceno
= lj_lib_checkint(L
, 1);
83 luaJIT_setmode(L
, traceno
, LUAJIT_MODE_FLUSH
|LUAJIT_MODE_TRACE
);
87 return setjitmode(L
, LUAJIT_MODE_FLUSH
);
91 /* Push a string for every flag bit that is set. */
92 static void flagbits_to_strings(lua_State
*L
, uint32_t flags
, uint32_t base
,
95 for (; *str
; base
<<= 1, str
+= 1+*str
)
97 setstrV(L
, L
->top
++, lj_str_new(L
, str
+1, *(uint8_t *)str
));
104 jit_State
*J
= L2J(L
);
106 setboolV(L
->top
++, (J
->flags
& JIT_F_ON
) ? 1 : 0);
107 flagbits_to_strings(L
, J
->flags
, JIT_F_CPU
, JIT_F_CPUSTRING
);
108 flagbits_to_strings(L
, J
->flags
, JIT_F_OPT
, JIT_F_OPTSTRING
);
109 return (int)(L
->top
- L
->base
);
111 setboolV(L
->top
++, 0);
116 LJLIB_CF(jit_security
)
118 int idx
= lj_lib_checkopt(L
, 1, -1, LJ_SECURITY_MODESTRING
);
119 setintV(L
->top
++, ((LJ_SECURITY_MODE
>> (2*idx
)) & 3));
125 #ifdef LUAJIT_DISABLE_VMEVENT
126 luaL_error(L
, "vmevent API disabled");
128 GCfunc
*fn
= lj_lib_checkfunc(L
, 1);
129 GCstr
*s
= lj_lib_optstr(L
, 2);
130 luaL_findtable(L
, LUA_REGISTRYINDEX
, LJ_VMEVENTS_REGKEY
, LJ_VMEVENTS_HSIZE
);
131 if (s
) { /* Attach to given event. */
132 const uint8_t *p
= (const uint8_t *)strdata(s
);
134 while (*p
) h
= h
^ (lj_rol(h
, 6) + *p
++);
136 lua_rawseti(L
, -2, VMEVENT_HASHIDX(h
));
137 G(L
)->vmevmask
= VMEVENT_NOCACHE
; /* Invalidate cache. */
138 } else { /* Detach if no event given. */
140 while (lua_next(L
, -2)) {
142 if (tvisfunc(L
->top
) && funcV(L
->top
) == fn
) {
143 setnilV(lj_tab_set(L
, tabV(L
->top
-2), L
->top
-1));
151 LJLIB_PUSH(top
-5) LJLIB_SET(os
)
152 LJLIB_PUSH(top
-4) LJLIB_SET(arch
)
153 LJLIB_PUSH(top
-3) LJLIB_SET(version_num
)
154 LJLIB_PUSH(top
-2) LJLIB_SET(version
)
156 #include "lj_libdef.h"
158 /* -- jit.util.* functions ------------------------------------------------ */
160 #define LJLIB_MODULE_jit_util
162 /* -- Reflection API for Lua functions ------------------------------------ */
164 /* Return prototype of first argument (Lua function or prototype object) */
165 static GCproto
*check_Lproto(lua_State
*L
, int nolua
)
171 } else if (tvisfunc(o
)) {
172 if (isluafunc(funcV(o
)))
173 return funcproto(funcV(o
));
178 lj_err_argt(L
, 1, LUA_TFUNCTION
);
179 return NULL
; /* unreachable */
182 static void setintfield(lua_State
*L
, GCtab
*t
, const char *name
, int32_t val
)
184 setintV(lj_tab_setstr(L
, t
, lj_str_newz(L
, name
)), val
);
187 /* local info = jit.util.funcinfo(func [,pc]) */
188 LJLIB_CF(jit_util_funcinfo
)
190 GCproto
*pt
= check_Lproto(L
, 1);
192 BCPos pc
= (BCPos
)lj_lib_optint(L
, 2, 0);
194 lua_createtable(L
, 0, 16); /* Increment hash size if fields are added. */
196 setintfield(L
, t
, "linedefined", pt
->firstline
);
197 setintfield(L
, t
, "lastlinedefined", pt
->firstline
+ pt
->numline
);
198 setintfield(L
, t
, "stackslots", pt
->framesize
);
199 setintfield(L
, t
, "params", pt
->numparams
);
200 setintfield(L
, t
, "bytecodes", (int32_t)pt
->sizebc
);
201 setintfield(L
, t
, "gcconsts", (int32_t)pt
->sizekgc
);
202 setintfield(L
, t
, "nconsts", (int32_t)pt
->sizekn
);
203 setintfield(L
, t
, "upvalues", (int32_t)pt
->sizeuv
);
205 setintfield(L
, t
, "currentline", lj_debug_line(pt
, pc
));
206 lua_pushboolean(L
, (pt
->flags
& PROTO_VARARG
));
207 lua_setfield(L
, -2, "isvararg");
208 lua_pushboolean(L
, (pt
->flags
& PROTO_CHILD
));
209 lua_setfield(L
, -2, "children");
210 setstrV(L
, L
->top
++, proto_chunkname(pt
));
211 lua_setfield(L
, -2, "source");
212 lj_debug_pushloc(L
, pt
, pc
);
213 lua_setfield(L
, -2, "loc");
214 setprotoV(L
, lj_tab_setstr(L
, t
, lj_str_newlit(L
, "proto")), pt
);
216 GCfunc
*fn
= funcV(L
->base
);
218 lua_createtable(L
, 0, 4); /* Increment hash size if fields are added. */
221 setintfield(L
, t
, "ffid", fn
->c
.ffid
);
222 setintptrV(lj_tab_setstr(L
, t
, lj_str_newlit(L
, "addr")),
223 (intptr_t)(void *)fn
->c
.f
);
224 setintfield(L
, t
, "upvalues", fn
->c
.nupvalues
);
229 /* local ins, m = jit.util.funcbc(func, pc) */
230 LJLIB_CF(jit_util_funcbc
)
232 GCproto
*pt
= check_Lproto(L
, 0);
233 BCPos pc
= (BCPos
)lj_lib_checkint(L
, 2);
234 if (pc
< pt
->sizebc
) {
235 BCIns ins
= proto_bc(pt
)[pc
];
236 BCOp op
= bc_op(ins
);
237 lj_assertL(op
< BC__MAX
, "bad bytecode op %d", op
);
238 setintV(L
->top
, ins
);
239 setintV(L
->top
+1, lj_bc_mode
[op
]);
246 /* local k = jit.util.funck(func, idx) */
247 LJLIB_CF(jit_util_funck
)
249 GCproto
*pt
= check_Lproto(L
, 0);
250 ptrdiff_t idx
= (ptrdiff_t)lj_lib_checkint(L
, 2);
252 if (idx
< (ptrdiff_t)pt
->sizekn
) {
253 copyTV(L
, L
->top
-1, proto_knumtv(pt
, idx
));
257 if (~idx
< (ptrdiff_t)pt
->sizekgc
) {
258 GCobj
*gc
= proto_kgc(pt
, idx
);
259 setgcV(L
, L
->top
-1, gc
, ~gc
->gch
.gct
);
266 /* local name = jit.util.funcuvname(func, idx) */
267 LJLIB_CF(jit_util_funcuvname
)
269 GCproto
*pt
= check_Lproto(L
, 0);
270 uint32_t idx
= (uint32_t)lj_lib_checkint(L
, 2);
271 if (idx
< pt
->sizeuv
) {
272 setstrV(L
, L
->top
-1, lj_str_newz(L
, lj_debug_uvname(pt
, idx
)));
278 /* -- Reflection API for traces ------------------------------------------- */
282 /* Check trace argument. Must not throw for non-existent trace numbers. */
283 static GCtrace
*jit_checktrace(lua_State
*L
)
285 TraceNo tr
= (TraceNo
)lj_lib_checkint(L
, 1);
286 jit_State
*J
= L2J(L
);
287 if (tr
> 0 && tr
< J
->sizetrace
)
288 return traceref(J
, tr
);
292 /* Names of link types. ORDER LJ_TRLINK */
293 static const char *const jit_trlinkname
[] = {
294 "none", "root", "loop", "tail-recursion", "up-recursion", "down-recursion",
295 "interpreter", "return", "stitch"
298 /* local info = jit.util.traceinfo(tr) */
299 LJLIB_CF(jit_util_traceinfo
)
301 GCtrace
*T
= jit_checktrace(L
);
304 lua_createtable(L
, 0, 8); /* Increment hash size if fields are added. */
306 setintfield(L
, t
, "nins", (int32_t)T
->nins
- REF_BIAS
- 1);
307 setintfield(L
, t
, "nk", REF_BIAS
- (int32_t)T
->nk
);
308 setintfield(L
, t
, "link", T
->link
);
309 setintfield(L
, t
, "nexit", T
->nsnap
);
310 setstrV(L
, L
->top
++, lj_str_newz(L
, jit_trlinkname
[T
->linktype
]));
311 lua_setfield(L
, -2, "linktype");
312 /* There are many more fields. Add them only when needed. */
318 /* local m, ot, op1, op2, prev = jit.util.traceir(tr, idx) */
319 LJLIB_CF(jit_util_traceir
)
321 GCtrace
*T
= jit_checktrace(L
);
322 IRRef ref
= (IRRef
)lj_lib_checkint(L
, 2) + REF_BIAS
;
323 if (T
&& ref
>= REF_BIAS
&& ref
< T
->nins
) {
324 IRIns
*ir
= &T
->ir
[ref
];
325 int32_t m
= lj_ir_mode
[ir
->o
];
326 setintV(L
->top
-2, m
);
327 setintV(L
->top
-1, ir
->ot
);
328 setintV(L
->top
++, (int32_t)ir
->op1
- (irm_op1(m
)==IRMref
? REF_BIAS
: 0));
329 setintV(L
->top
++, (int32_t)ir
->op2
- (irm_op2(m
)==IRMref
? REF_BIAS
: 0));
330 setintV(L
->top
++, ir
->prev
);
336 /* local k, t [, slot] = jit.util.tracek(tr, idx) */
337 LJLIB_CF(jit_util_tracek
)
339 GCtrace
*T
= jit_checktrace(L
);
340 IRRef ref
= (IRRef
)lj_lib_checkint(L
, 2) + REF_BIAS
;
341 if (T
&& ref
>= T
->nk
&& ref
< REF_BIAS
) {
342 IRIns
*ir
= &T
->ir
[ref
];
344 if (ir
->o
== IR_KSLOT
) {
346 ir
= &T
->ir
[ir
->op1
];
349 if (ir
->o
== IR_KINT64
) ctype_loadffi(L
);
351 lj_ir_kvalue(L
, L
->top
-2, ir
);
352 setintV(L
->top
-1, (int32_t)irt_type(ir
->t
));
355 setintV(L
->top
++, slot
);
361 /* local snap = jit.util.tracesnap(tr, sn) */
362 LJLIB_CF(jit_util_tracesnap
)
364 GCtrace
*T
= jit_checktrace(L
);
365 SnapNo sn
= (SnapNo
)lj_lib_checkint(L
, 2);
366 if (T
&& sn
< T
->nsnap
) {
367 SnapShot
*snap
= &T
->snap
[sn
];
368 SnapEntry
*map
= &T
->snapmap
[snap
->mapofs
];
369 MSize n
, nent
= snap
->nent
;
371 lua_createtable(L
, nent
+2, 0);
373 setintV(lj_tab_setint(L
, t
, 0), (int32_t)snap
->ref
- REF_BIAS
);
374 setintV(lj_tab_setint(L
, t
, 1), (int32_t)snap
->nslots
);
375 for (n
= 0; n
< nent
; n
++)
376 setintV(lj_tab_setint(L
, t
, (int32_t)(n
+2)), (int32_t)map
[n
]);
377 setintV(lj_tab_setint(L
, t
, (int32_t)(nent
+2)), (int32_t)SNAP(255, 0, 0));
383 /* local mcode, addr, loop = jit.util.tracemc(tr) */
384 LJLIB_CF(jit_util_tracemc
)
386 GCtrace
*T
= jit_checktrace(L
);
387 if (T
&& T
->mcode
!= NULL
) {
388 setstrV(L
, L
->top
-1, lj_str_new(L
, (const char *)T
->mcode
, T
->szmcode
));
389 setintptrV(L
->top
++, (intptr_t)(void *)T
->mcode
);
390 setintV(L
->top
++, T
->mcloop
);
396 /* local addr = jit.util.traceexitstub([tr,] exitno) */
397 LJLIB_CF(jit_util_traceexitstub
)
399 #ifdef EXITSTUBS_PER_GROUP
400 ExitNo exitno
= (ExitNo
)lj_lib_checkint(L
, 1);
401 jit_State
*J
= L2J(L
);
402 if (exitno
< EXITSTUBS_PER_GROUP
*LJ_MAX_EXITSTUBGR
) {
403 setintptrV(L
->top
-1, (intptr_t)(void *)exitstub_addr(J
, exitno
));
407 if (L
->top
> L
->base
+1) { /* Don't throw for one-argument variant. */
408 GCtrace
*T
= jit_checktrace(L
);
409 ExitNo exitno
= (ExitNo
)lj_lib_checkint(L
, 2);
410 ExitNo maxexit
= T
->root
? T
->nsnap
+1 : T
->nsnap
;
411 if (T
&& T
->mcode
!= NULL
&& exitno
< maxexit
) {
412 setintptrV(L
->top
-1, (intptr_t)(void *)exitstub_trace_addr(T
, exitno
));
420 /* local addr = jit.util.ircalladdr(idx) */
421 LJLIB_CF(jit_util_ircalladdr
)
423 uint32_t idx
= (uint32_t)lj_lib_checkint(L
, 1);
424 if (idx
< IRCALL__MAX
) {
425 ASMFunction func
= lj_ir_callinfo
[idx
].func
;
426 setintptrV(L
->top
-1, (intptr_t)(void *)lj_ptr_strip(func
));
434 #include "lj_libdef.h"
436 static int luaopen_jit_util(lua_State
*L
)
438 LJ_LIB_REG(L
, NULL
, jit_util
);
442 /* -- jit.opt module ------------------------------------------------------ */
446 #define LJLIB_MODULE_jit_opt
448 /* Parse optimization level. */
449 static int jitopt_level(jit_State
*J
, const char *str
)
451 if (str
[0] >= '0' && str
[0] <= '9' && str
[1] == '\0') {
453 if (str
[0] == '0') flags
= JIT_F_OPT_0
;
454 else if (str
[0] == '1') flags
= JIT_F_OPT_1
;
455 else if (str
[0] == '2') flags
= JIT_F_OPT_2
;
456 else flags
= JIT_F_OPT_3
;
457 J
->flags
= (J
->flags
& ~JIT_F_OPT_MASK
) | flags
;
460 return 0; /* No match. */
463 /* Parse optimization flag. */
464 static int jitopt_flag(jit_State
*J
, const char *str
)
466 const char *lst
= JIT_F_OPTSTRING
;
471 } else if (str
[0] == '-') {
474 } else if (str
[0] == 'n' && str
[1] == 'o') {
475 str
+= str
[2] == '-' ? 3 : 2;
478 for (opt
= JIT_F_OPT
; ; opt
<<= 1) {
479 size_t len
= *(const uint8_t *)lst
;
482 if (strncmp(str
, lst
+1, len
) == 0 && str
[len
] == '\0') {
483 if (set
) J
->flags
|= opt
; else J
->flags
&= ~opt
;
488 return 0; /* No match. */
491 /* Parse optimization parameter. */
492 static int jitopt_param(jit_State
*J
, const char *str
)
494 const char *lst
= JIT_P_STRING
;
496 for (i
= 0; i
< JIT_P__MAX
; i
++) {
497 size_t len
= *(const uint8_t *)lst
;
498 lj_assertJ(len
!= 0, "bad JIT_P_STRING");
499 if (strncmp(str
, lst
+1, len
) == 0 && str
[len
] == '=') {
501 const char *p
= &str
[len
+1];
502 while (*p
>= '0' && *p
<= '9')
503 n
= n
*10 + (*p
++ - '0');
504 if (*p
) return 0; /* Malformed number. */
506 if (i
== JIT_P_hotloop
)
507 lj_dispatch_init_hotcount(J2G(J
));
512 return 0; /* No match. */
515 /* jit.opt.start(flags...) */
516 LJLIB_CF(jit_opt_start
)
518 jit_State
*J
= L2J(L
);
519 int nargs
= (int)(L
->top
- L
->base
);
521 J
->flags
= (J
->flags
& ~JIT_F_OPT_MASK
) | JIT_F_OPT_DEFAULT
;
524 for (i
= 1; i
<= nargs
; i
++) {
525 const char *str
= strdata(lj_lib_checkstr(L
, i
));
526 if (!jitopt_level(J
, str
) &&
527 !jitopt_flag(J
, str
) &&
528 !jitopt_param(J
, str
))
529 lj_err_callerv(L
, LJ_ERR_JITOPT
, str
);
535 #include "lj_libdef.h"
539 /* -- jit.profile module -------------------------------------------------- */
543 #define LJLIB_MODULE_jit_profile
545 /* Not loaded by default, use: local profile = require("jit.profile") */
547 #define KEY_PROFILE_THREAD (U64x(80000000,00000000)|'t')
548 #define KEY_PROFILE_FUNC (U64x(80000000,00000000)|'f')
550 static void jit_profile_callback(lua_State
*L2
, lua_State
*L
, int samples
,
555 key
.u64
= KEY_PROFILE_FUNC
;
556 tv
= lj_tab_get(L
, tabV(registry(L
)), &key
);
558 char vmst
= (char)vmstate
;
560 setfuncV(L2
, L2
->top
++, funcV(tv
));
561 setthreadV(L2
, L2
->top
++, L
);
562 setintV(L2
->top
++, samples
);
563 setstrV(L2
, L2
->top
++, lj_str_new(L2
, &vmst
, 1));
564 status
= lua_pcall(L2
, 3, 0, 0); /* callback(thread, samples, vmstate) */
566 if (G(L2
)->panic
) G(L2
)->panic(L2
);
569 lj_trace_abort(G(L2
));
573 /* profile.start(mode, cb) */
574 LJLIB_CF(jit_profile_start
)
576 GCtab
*registry
= tabV(registry(L
));
577 GCstr
*mode
= lj_lib_optstr(L
, 1);
578 GCfunc
*func
= lj_lib_checkfunc(L
, 2);
579 lua_State
*L2
= lua_newthread(L
); /* Thread that runs profiler callback. */
581 /* Anchor thread and function in registry. */
582 key
.u64
= KEY_PROFILE_THREAD
;
583 setthreadV(L
, lj_tab_set(L
, registry
, &key
), L2
);
584 key
.u64
= KEY_PROFILE_FUNC
;
585 setfuncV(L
, lj_tab_set(L
, registry
, &key
), func
);
586 lj_gc_anybarriert(L
, registry
);
587 luaJIT_profile_start(L
, mode
? strdata(mode
) : "",
588 (luaJIT_profile_callback
)jit_profile_callback
, L2
);
593 LJLIB_CF(jit_profile_stop
)
597 luaJIT_profile_stop(L
);
598 registry
= tabV(registry(L
));
599 key
.u64
= KEY_PROFILE_THREAD
;
600 setnilV(lj_tab_set(L
, registry
, &key
));
601 key
.u64
= KEY_PROFILE_FUNC
;
602 setnilV(lj_tab_set(L
, registry
, &key
));
603 lj_gc_anybarriert(L
, registry
);
607 /* dump = profile.dumpstack([thread,] fmt, depth) */
608 LJLIB_CF(jit_profile_dumpstack
)
616 if (L
->top
> L
->base
&& tvisthread(L
->base
)) {
617 L2
= threadV(L
->base
);
620 fmt
= lj_lib_checkstr(L
, arg
+1);
621 depth
= lj_lib_checkint(L
, arg
+2);
622 p
= luaJIT_profile_dumpstack(L2
, strdata(fmt
), depth
, &len
);
623 lua_pushlstring(L
, p
, len
);
627 #include "lj_libdef.h"
629 static int luaopen_jit_profile(lua_State
*L
)
631 LJ_LIB_REG(L
, NULL
, jit_profile
);
637 /* -- JIT compiler initialization ----------------------------------------- */
640 /* Default values for JIT parameters. */
641 static const int32_t jit_param_default
[JIT_P__MAX
+1] = {
642 #define JIT_PARAMINIT(len, name, value) (value),
643 JIT_PARAMDEF(JIT_PARAMINIT
)
648 #if LJ_TARGET_ARM && LJ_TARGET_LINUX
649 #include <sys/utsname.h>
652 /* Arch-dependent CPU feature detection. */
653 static uint32_t jit_cpudetect(void)
656 #if LJ_TARGET_X86ORX64
659 uint32_t features
[4];
660 if (lj_vm_cpuid(0, vendor
) && lj_vm_cpuid(1, features
)) {
661 flags
|= ((features
[2] >> 0)&1) * JIT_F_SSE3
;
662 flags
|= ((features
[2] >> 19)&1) * JIT_F_SSE4_1
;
663 if (vendor
[0] >= 7) {
664 uint32_t xfeatures
[4];
665 lj_vm_cpuid(7, xfeatures
);
666 flags
|= ((xfeatures
[1] >> 8)&1) * JIT_F_BMI2
;
669 /* Don't bother checking for SSE2 -- the VM will crash before getting here. */
673 int ver
= LJ_ARCH_VERSION
; /* Compile-time ARM CPU detection. */
675 if (ver
< 70) { /* Runtime ARM CPU detection. */
678 if (strncmp(ut
.machine
, "armv", 4) == 0) {
679 if (ut
.machine
[4] >= '8') ver
= 80;
680 else if (ut
.machine
[4] == '7') ver
= 70;
681 else if (ut
.machine
[4] == '6') ver
= 60;
685 flags
|= ver
>= 70 ? JIT_F_ARMV7
:
686 ver
>= 61 ? JIT_F_ARMV6T2_
:
687 ver
>= 60 ? JIT_F_ARMV6_
: 0;
688 flags
|= LJ_ARCH_HASFPU
== 0 ? 0 : ver
>= 70 ? JIT_F_VFPV3
: JIT_F_VFPV2
;
690 #elif LJ_TARGET_ARM64
692 /* No optional CPU features to detect (for now). */
700 flags
|= JIT_F_ROUND
;
705 /* Compile-time MIPS CPU detection. */
706 #if LJ_ARCH_VERSION >= 20
707 flags
|= JIT_F_MIPSXXR2
;
709 /* Runtime MIPS CPU detection. */
710 #if defined(__GNUC__)
711 if (!(flags
& JIT_F_MIPSXXR2
)) {
714 x
= 0; /* Runtime detection is difficult. Ensure optimal -march flags. */
716 /* On MIPS32R1 rotr is treated as srl. rotr r2,r2,1 -> srl r2,r2,1. */
717 __asm__("li $2, 1\n\t.long 0x00221042\n\tmove %0, $2" : "=r"(x
) : : "$2");
719 if (x
) flags
|= JIT_F_MIPSXXR2
; /* Either 0x80000000 (R2) or 0 (R1). */
724 #error "Missing CPU detection for this architecture"
729 /* Initialize JIT compiler. */
730 static void jit_init(lua_State
*L
)
732 jit_State
*J
= L2J(L
);
733 J
->flags
= jit_cpudetect() | JIT_F_ON
| JIT_F_OPT_DEFAULT
;
734 memcpy(J
->param
, jit_param_default
, sizeof(J
->param
));
735 lj_dispatch_update(G(L
));
739 LUALIB_API
int luaopen_jit(lua_State
*L
)
744 lua_pushliteral(L
, LJ_OS_NAME
);
745 lua_pushliteral(L
, LJ_ARCH_NAME
);
746 lua_pushinteger(L
, LUAJIT_VERSION_NUM
); /* Deprecated. */
747 lua_pushliteral(L
, LUAJIT_VERSION
);
748 LJ_LIB_REG(L
, LUA_JITLIBNAME
, jit
);
750 lj_lib_prereg(L
, LUA_JITLIBNAME
".profile", luaopen_jit_profile
,
753 #ifndef LUAJIT_DISABLE_JITUTIL
754 lj_lib_prereg(L
, LUA_JITLIBNAME
".util", luaopen_jit_util
, tabref(L
->env
));
757 LJ_LIB_REG(L
, "jit.opt", jit_opt
);