├── .gitattributes
├── .gitignore
├── .relver
├── .travis.yml
├── COPYRIGHT
├── Makefile
├── README
├── README.md
├── doc
├── bluequad-print.css
├── bluequad.css
├── contact.html
├── ext_buffer.html
├── ext_c_api.html
├── ext_ffi.html
├── ext_ffi_api.html
├── ext_ffi_semantics.html
├── ext_ffi_tutorial.html
├── ext_jit.html
├── ext_profiler.html
├── extensions.html
├── img
│ └── contact.png
├── install.html
├── luajit.html
└── running.html
├── dynasm
├── Examples
│ ├── run.sh
│ └── test_z_inst.c
├── dasm_arm.h
├── dasm_arm.lua
├── dasm_arm64.h
├── dasm_arm64.lua
├── dasm_mips.h
├── dasm_mips.lua
├── dasm_mips64.lua
├── dasm_ppc.h
├── dasm_ppc.lua
├── dasm_proto.h
├── dasm_s390x.h
├── dasm_s390x.lua
├── dasm_x64.lua
├── dasm_x86.h
├── dasm_x86.lua
└── dynasm.lua
├── etc
├── luajit.1
└── luajit.pc
├── src
├── .gitignore
├── Makefile
├── Makefile.dep
├── host
│ ├── .gitignore
│ ├── README
│ ├── buildvm.c
│ ├── buildvm.h
│ ├── buildvm_asm.c
│ ├── buildvm_fold.c
│ ├── buildvm_lib.c
│ ├── buildvm_libbc.h
│ ├── buildvm_peobj.c
│ ├── genlibbc.lua
│ ├── genminilua.lua
│ ├── genversion.lua
│ └── minilua.c
├── jit
│ ├── .gitignore
│ ├── bc.lua
│ ├── bcsave.lua
│ ├── dis_arm.lua
│ ├── dis_arm64.lua
│ ├── dis_arm64be.lua
│ ├── dis_mips.lua
│ ├── dis_mips64.lua
│ ├── dis_mips64el.lua
│ ├── dis_mips64r6.lua
│ ├── dis_mips64r6el.lua
│ ├── dis_mipsel.lua
│ ├── dis_ppc.lua
│ ├── dis_s390x.lua
│ ├── dis_x64.lua
│ ├── dis_x86.lua
│ ├── dump.lua
│ ├── p.lua
│ ├── v.lua
│ └── zone.lua
├── lauxlib.h
├── lib_aux.c
├── lib_base.c
├── lib_bit.c
├── lib_buffer.c
├── lib_debug.c
├── lib_ffi.c
├── lib_init.c
├── lib_io.c
├── lib_jit.c
├── lib_math.c
├── lib_os.c
├── lib_package.c
├── lib_string.c
├── lib_table.c
├── lj_alloc.c
├── lj_alloc.h
├── lj_api.c
├── lj_arch.h
├── lj_asm.c
├── lj_asm.h
├── lj_asm_arm.h
├── lj_asm_arm64.h
├── lj_asm_mips.h
├── lj_asm_ppc.h
├── lj_asm_x86.h
├── lj_assert.c
├── lj_bc.c
├── lj_bc.h
├── lj_bcdump.h
├── lj_bcread.c
├── lj_bcwrite.c
├── lj_buf.c
├── lj_buf.h
├── lj_carith.c
├── lj_carith.h
├── lj_ccall.c
├── lj_ccall.h
├── lj_ccallback.c
├── lj_ccallback.h
├── lj_cconv.c
├── lj_cconv.h
├── lj_cdata.c
├── lj_cdata.h
├── lj_char.c
├── lj_char.h
├── lj_clib.c
├── lj_clib.h
├── lj_cparse.c
├── lj_cparse.h
├── lj_crecord.c
├── lj_crecord.h
├── lj_ctype.c
├── lj_ctype.h
├── lj_debug.c
├── lj_debug.h
├── lj_def.h
├── lj_dispatch.c
├── lj_dispatch.h
├── lj_emit_arm.h
├── lj_emit_arm64.h
├── lj_emit_mips.h
├── lj_emit_ppc.h
├── lj_emit_x86.h
├── lj_err.c
├── lj_err.h
├── lj_errmsg.h
├── lj_ff.h
├── lj_ffrecord.c
├── lj_ffrecord.h
├── lj_frame.h
├── lj_func.c
├── lj_func.h
├── lj_gc.c
├── lj_gc.h
├── lj_gdbjit.c
├── lj_gdbjit.h
├── lj_init.c
├── lj_ir.c
├── lj_ir.h
├── lj_ircall.h
├── lj_iropt.h
├── lj_jit.h
├── lj_lex.c
├── lj_lex.h
├── lj_lib.c
├── lj_lib.h
├── lj_load.c
├── lj_mcode.c
├── lj_mcode.h
├── lj_meta.c
├── lj_meta.h
├── lj_obj.c
├── lj_obj.h
├── lj_opt_dce.c
├── lj_opt_fold.c
├── lj_opt_loop.c
├── lj_opt_mem.c
├── lj_opt_narrow.c
├── lj_opt_sink.c
├── lj_opt_split.c
├── lj_parse.c
├── lj_parse.h
├── lj_prng.c
├── lj_prng.h
├── lj_profile.c
├── lj_profile.h
├── lj_record.c
├── lj_record.h
├── lj_serialize.c
├── lj_serialize.h
├── lj_snap.c
├── lj_snap.h
├── lj_state.c
├── lj_state.h
├── lj_str.c
├── lj_str.h
├── lj_str_hash.c
├── lj_strfmt.c
├── lj_strfmt.h
├── lj_strfmt_num.c
├── lj_strscan.c
├── lj_strscan.h
├── lj_tab.c
├── lj_tab.h
├── lj_target.h
├── lj_target_arm.h
├── lj_target_arm64.h
├── lj_target_mips.h
├── lj_target_ppc.h
├── lj_target_s390x.h
├── lj_target_x86.h
├── lj_trace.c
├── lj_trace.h
├── lj_traceerr.h
├── lj_udata.c
├── lj_udata.h
├── lj_vm.h
├── lj_vmevent.c
├── lj_vmevent.h
├── lj_vmmath.c
├── ljamalg.c
├── lua.h
├── lua.hpp
├── luaconf.h
├── luajit.c
├── luajit_rolling.h
├── lualib.h
├── msvcbuild.bat
├── nxbuild.bat
├── ps4build.bat
├── ps5build.bat
├── psvitabuild.bat
├── vm_arm.dasc
├── vm_arm64.dasc
├── vm_mips.dasc
├── vm_mips64.dasc
├── vm_ppc.dasc
├── vm_s390x.dasc
├── vm_x64.dasc
├── vm_x86.dasc
├── x64
│ ├── Makefile
│ └── test
│ │ ├── Makefile
│ │ ├── benchmark.cxx
│ │ ├── test.cpp
│ │ ├── test_str_comp.lua
│ │ ├── test_util.cxx
│ │ ├── test_util.d
│ │ └── test_util.hpp
├── xb1build.bat
└── xedkbuild.bat
└── t
├── TestLJ.pm
├── exdata.t
├── exdata2.t
├── isarr-interp.t
├── isarr-jit.t
├── isempty.t
├── iter.t
├── nkeys.t
├── prngstate.t
└── table-clone.t
/.gitattributes:
--------------------------------------------------------------------------------
1 | /.relver export-subst
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.[oa]
2 | *.so
3 | *.obj
4 | *.lib
5 | *.exp
6 | *.dll
7 | *.exe
8 | *.manifest
9 | *.dmp
10 | *.swp
11 | .tags
12 | *~
13 | tags
14 | *.swo
15 |
--------------------------------------------------------------------------------
/.relver:
--------------------------------------------------------------------------------
1 | 1748495995
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: required
2 | dist: focal
3 |
4 | branches:
5 | only:
6 | - "v2.1-agentzh"
7 |
8 | os: linux
9 | arch:
10 | - amd64
11 | - arm64
12 | - s390x
13 | - ppc64le
14 |
15 | language: c
16 |
17 | compiler:
18 | - gcc
19 |
20 | addons:
21 | apt:
22 | packages:
23 | - axel
24 | - cpanminus
25 | - libtest-base-perl
26 | - libtext-diff-perl
27 | - libtest-longstring-perl
28 | - liblist-moreutils-perl
29 | - libparallel-forkmanager-perl
30 | - libgd-dev
31 | - libmpc-dev
32 | - build-essential
33 | - libgtk2.0-dev
34 | - valgrind
35 |
36 | env:
37 | global:
38 | - JOBS=3
39 | - LUAJIT_PREFIX=/opt/luajit21
40 | - LUAJIT_SYSM_PREFIX=/opt/luajit21-sysm
41 | - LUAJIT_COMMON_XCFLAGS="-DLUA_USE_APICHECK -DLUA_USE_ASSERT -DLUAJIT_NUMMODE=2 -O1"
42 | - LUAJIT_COMMON_XCFLAGS=$( [ ${TRAVIS_CPU_ARCH} == "amd64" ] && echo "$LUAJIT_COMMON_XCFLAGS -msse4.2" || echo "$LUAJIT_COMMON_XCFLAGS" )
43 |
44 | matrix:
45 | - LUAJIT_XCFLAGS="$LUAJIT_COMMON_XCFLAGS"
46 | - LUAJIT_XCFLAGS="-DLUAJIT_ENABLE_LUA52COMPAT $LUAJIT_COMMON_XCFLAGS" LUA52=1
47 | - LUAJIT_XCFLAGS="-DLUAJIT_USE_VALGRIND -DLUAJIT_USE_SYSMALLOC -DLUAJIT_ENABLE_LUA52COMPAT $LUAJIT_COMMON_XCFLAGS" LUA52=1 FLAGS=$( [ ${TRAVIS_CPU_ARCH} != "s390x" ] && echo '-v' )
48 | - LUAJIT_XCFLAGS="-DLUAJIT_DISABLE_GC64 -DLUAJIT_ENABLE_LUA52COMPAT $LUAJIT_COMMON_XCFLAGS" LUA52=1
49 |
50 | install:
51 | - git clone https://github.com/openresty/luajit2-test-suite.git ../luajit2-test-suite
52 |
53 | script:
54 | - echo ${LUAJIT_COMMON_XCFLAGS}
55 | - valgrind --version
56 | - /usr/bin/env perl $(command -v cpanm) --sudo --notest IPC::Run3 Test::Base Test::LongString Parallel::ForkManager > build.log 2>&1 || (cat build.log && exit 1)
57 | - cd ../luajit2
58 | - make -j$JOBS CCDEBUG=-g Q= PREFIX=$LUAJIT_PREFIX CC=$CC XCFLAGS="$LUAJIT_XCFLAGS" > build.log 2>&1 || (cat build.log && exit 1)
59 | - sudo make install PREFIX=$LUAJIT_PREFIX > build.log 2>&1 || (cat build.log && exit 1)
60 | - if [ ${TRAVIS_CPU_ARCH} == "amd64" ]; then PATH=/opt/luajit21/bin:$PATH prove -I. t; fi
61 | - cd ../luajit2-test-suite
62 | - ./run-tests -j 1 $FLAGS $LUAJIT_PREFIX
63 |
--------------------------------------------------------------------------------
/COPYRIGHT:
--------------------------------------------------------------------------------
1 | ===============================================================================
2 | LuaJIT -- a Just-In-Time Compiler for Lua. https://luajit.org/
3 |
4 | Copyright (C) 2005-2025 Mike Pall. All rights reserved.
5 |
6 | Copyright (C) 2017-2018 Yichun Zhang. All rights reserved.
7 |
8 | Copyright (C) 2017-2018 OpenResty Inc. All rights reserved.
9 |
10 | Permission is hereby granted, free of charge, to any person obtaining a copy
11 | of this software and associated documentation files (the "Software"), to deal
12 | in the Software without restriction, including without limitation the rights
13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | copies of the Software, and to permit persons to whom the Software is
15 | furnished to do so, subject to the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included in
18 | all copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 | THE SOFTWARE.
27 |
28 | [ MIT license: https://www.opensource.org/licenses/mit-license.php ]
29 |
30 | ===============================================================================
31 | [ LuaJIT includes code from Lua 5.1/5.2, which has this license statement: ]
32 |
33 | Copyright (C) 1994-2012 Lua.org, PUC-Rio.
34 |
35 | Permission is hereby granted, free of charge, to any person obtaining a copy
36 | of this software and associated documentation files (the "Software"), to deal
37 | in the Software without restriction, including without limitation the rights
38 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
39 | copies of the Software, and to permit persons to whom the Software is
40 | furnished to do so, subject to the following conditions:
41 |
42 | The above copyright notice and this permission notice shall be included in
43 | all copies or substantial portions of the Software.
44 |
45 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
51 | THE SOFTWARE.
52 |
53 | ===============================================================================
54 | [ LuaJIT includes code from dlmalloc, which has this license statement: ]
55 |
56 | This is a version (aka dlmalloc) of malloc/free/realloc written by
57 | Doug Lea and released to the public domain, as explained at
58 | https://creativecommons.org/licenses/publicdomain
59 |
60 | ===============================================================================
61 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | README for LuaJIT 2.1
2 | ---------------------
3 |
4 | LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
5 |
6 | Project Homepage: https://luajit.org/
7 |
8 | LuaJIT is Copyright (C) 2005-2025 Mike Pall.
9 | LuaJIT is free software, released under the MIT license.
10 | See full Copyright Notice in the COPYRIGHT file or in luajit.h.
11 |
12 | Documentation for LuaJIT is available in HTML format.
13 | Please point your favorite browser to:
14 |
15 | doc/luajit.html
16 |
17 |
--------------------------------------------------------------------------------
/doc/bluequad-print.css:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2004-2025 Mike Pall.
2 | *
3 | * You are welcome to use the general ideas of this design for your own sites.
4 | * But please do not steal the stylesheet, the layout or the color scheme.
5 | */
6 | body {
7 | font-family: serif;
8 | font-size: 11pt;
9 | margin: 0 3em;
10 | padding: 0;
11 | border: none;
12 | }
13 | a:link, a:visited, a:hover, a:active {
14 | text-decoration: none;
15 | background: transparent;
16 | color: #0000ff;
17 | }
18 | h1, h2, h3 {
19 | font-family: sans-serif;
20 | font-weight: bold;
21 | text-align: left;
22 | margin: 0.5em 0;
23 | padding: 0;
24 | }
25 | h1 {
26 | font-size: 200%;
27 | }
28 | h2 {
29 | font-size: 150%;
30 | }
31 | h3 {
32 | font-size: 125%;
33 | }
34 | p {
35 | margin: 0 0 0.5em 0;
36 | padding: 0;
37 | }
38 | ul, ol {
39 | margin: 0.5em 0;
40 | padding: 0 0 0 2em;
41 | }
42 | ul {
43 | list-style: outside square;
44 | }
45 | ol {
46 | list-style: outside decimal;
47 | }
48 | li {
49 | margin: 0;
50 | padding: 0;
51 | }
52 | dl {
53 | margin: 1em 0;
54 | padding: 1em;
55 | border: 1px solid black;
56 | }
57 | dt {
58 | font-weight: bold;
59 | margin: 0;
60 | padding: 0;
61 | }
62 | dt sup {
63 | float: right;
64 | margin-left: 1em;
65 | }
66 | dd {
67 | margin: 0.5em 0 0 2em;
68 | padding: 0;
69 | }
70 | table {
71 | table-layout: fixed;
72 | width: 100%;
73 | margin: 1em 0;
74 | padding: 0;
75 | border: 1px solid black;
76 | border-spacing: 0;
77 | border-collapse: collapse;
78 | }
79 | tr {
80 | margin: 0;
81 | padding: 0;
82 | border: none;
83 | }
84 | td {
85 | text-align: left;
86 | margin: 0;
87 | padding: 0.2em 0.5em;
88 | border-top: 1px solid black;
89 | border-bottom: 1px solid black;
90 | }
91 | tr.separate td {
92 | border-top: double;
93 | }
94 | tt, pre, code, kbd, samp {
95 | font-family: monospace;
96 | font-size: 75%;
97 | }
98 | kbd {
99 | font-weight: bolder;
100 | }
101 | blockquote, pre {
102 | margin: 1em 2em;
103 | padding: 0;
104 | }
105 | img {
106 | border: none;
107 | vertical-align: baseline;
108 | margin: 0;
109 | padding: 0;
110 | }
111 | img.left {
112 | float: left;
113 | margin: 0.5em 1em 0.5em 0;
114 | }
115 | img.right {
116 | float: right;
117 | margin: 0.5em 0 0.5em 1em;
118 | }
119 | .flush {
120 | clear: both;
121 | visibility: hidden;
122 | }
123 | .hide, .noprint, #nav {
124 | display: none !important;
125 | }
126 | .pagebreak {
127 | page-break-before: always;
128 | }
129 | #site {
130 | text-align: right;
131 | font-family: sans-serif;
132 | font-weight: bold;
133 | margin: 0 1em;
134 | border-bottom: 1pt solid black;
135 | }
136 | #site a {
137 | font-size: 1.2em;
138 | }
139 | #site a:link, #site a:visited {
140 | text-decoration: none;
141 | font-weight: bold;
142 | background: transparent;
143 | color: #ffffff;
144 | }
145 | #logo {
146 | color: #ff8000;
147 | }
148 | #head {
149 | clear: both;
150 | margin: 0 1em;
151 | }
152 | #main {
153 | line-height: 1.3;
154 | text-align: justify;
155 | margin: 1em;
156 | }
157 | #foot {
158 | clear: both;
159 | font-size: 80%;
160 | text-align: center;
161 | margin: 0 1.25em;
162 | padding: 0.5em 0 0 0;
163 | border-top: 1pt solid black;
164 | page-break-before: avoid;
165 | page-break-after: avoid;
166 | }
167 |
--------------------------------------------------------------------------------
/doc/contact.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Contact
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
Contact
17 |
18 |
56 |
57 |
58 | If you want to report bugs, propose fixes or suggest enhancements,
59 | please use the
60 | » GitHub issue tracker .
61 |
62 |
63 | Please send general questions to the
64 | » LuaJIT mailing list .
65 |
66 |
67 | You can also send any questions you have directly to me:
68 |
69 |
70 |
78 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | Note: I cannot reply to GMail, Google Workplace, Outlook or Office365
89 | mail addresses, since they prefer to mindlessly filter out mails sent
90 | from small domains using independent mail servers, such as mine. If you
91 | don't like that, please complain to Google or Microsoft, not me.
92 |
93 |
94 |
Copyright
95 |
96 | All documentation is
97 | Copyright © 2005-2025 Mike Pall.
98 |
99 |
100 |
101 |
102 |
103 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/doc/img/contact.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openresty/luajit2/afc74313c6f919f713e2a25003cf0066852bb24a/doc/img/contact.png
--------------------------------------------------------------------------------
/dynasm/Examples/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # set -x
3 |
4 | # run test
5 | lua ../dynasm.lua test_z_inst.c | gcc -DDASM_CHECKS -std=gnu99 -Wall -Werror -g -x c -o test_z_inst -
6 | ./test_z_inst
7 | ec=$?
8 |
9 | # cleanup
10 | rm -f ./test_z_inst
11 |
12 | # exit
13 | exit $ec
14 |
15 |
--------------------------------------------------------------------------------
/dynasm/dasm_mips64.lua:
--------------------------------------------------------------------------------
1 | ------------------------------------------------------------------------------
2 | -- DynASM MIPS64 module.
3 | --
4 | -- Copyright (C) 2005-2025 Mike Pall. All rights reserved.
5 | -- See dynasm.lua for full copyright notice.
6 | ------------------------------------------------------------------------------
7 | -- This module just sets 64 bit mode for the combined MIPS/MIPS64 module.
8 | -- All the interesting stuff is there.
9 | ------------------------------------------------------------------------------
10 |
11 | mips64 = true -- Using a global is an ugly, but effective solution.
12 | return require("dasm_mips")
13 |
--------------------------------------------------------------------------------
/dynasm/dasm_proto.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** DynASM encoding engine prototypes.
3 | ** Copyright (C) 2005-2025 Mike Pall. All rights reserved.
4 | ** Released under the MIT license. See dynasm.lua for full copyright notice.
5 | */
6 |
7 | #ifndef _DASM_PROTO_H
8 | #define _DASM_PROTO_H
9 |
10 | #include
11 | #include
12 |
13 | #define DASM_IDENT "DynASM 1.5.0"
14 | #define DASM_VERSION 10500 /* 1.5.0 */
15 |
16 | #ifndef Dst_DECL
17 | #define Dst_DECL dasm_State **Dst
18 | #endif
19 |
20 | #ifndef Dst_REF
21 | #define Dst_REF (*Dst)
22 | #endif
23 |
24 | #ifndef DASM_FDEF
25 | #define DASM_FDEF extern
26 | #endif
27 |
28 | #ifndef DASM_M_GROW
29 | #define DASM_M_GROW(ctx, t, p, sz, need) \
30 | do { \
31 | size_t _sz = (sz), _need = (need); \
32 | if (_sz < _need) { \
33 | if (_sz < 16) _sz = 16; \
34 | while (_sz < _need) _sz += _sz; \
35 | (p) = (t *)realloc((p), _sz); \
36 | if ((p) == NULL) exit(1); \
37 | (sz) = _sz; \
38 | } \
39 | } while(0)
40 | #endif
41 |
42 | #ifndef DASM_M_FREE
43 | #define DASM_M_FREE(ctx, p, sz) free(p)
44 | #endif
45 |
46 | /* Internal DynASM encoder state. */
47 | typedef struct dasm_State dasm_State;
48 |
49 |
50 | /* Initialize and free DynASM state. */
51 | DASM_FDEF void dasm_init(Dst_DECL, int maxsection);
52 | DASM_FDEF void dasm_free(Dst_DECL);
53 |
54 | /* Setup global array. Must be called before dasm_setup(). */
55 | DASM_FDEF void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl);
56 |
57 | /* Grow PC label array. Can be called after dasm_setup(), too. */
58 | DASM_FDEF void dasm_growpc(Dst_DECL, unsigned int maxpc);
59 |
60 | /* Setup encoder. */
61 | DASM_FDEF void dasm_setup(Dst_DECL, const void *actionlist);
62 |
63 | /* Feed encoder with actions. Calls are generated by pre-processor. */
64 | DASM_FDEF void dasm_put(Dst_DECL, int start, ...);
65 |
66 | /* Link sections and return the resulting size. */
67 | DASM_FDEF int dasm_link(Dst_DECL, size_t *szp);
68 |
69 | /* Encode sections into buffer. */
70 | DASM_FDEF int dasm_encode(Dst_DECL, void *buffer);
71 |
72 | /* Get PC label offset. */
73 | DASM_FDEF int dasm_getpclabel(Dst_DECL, unsigned int pc);
74 |
75 | #ifdef DASM_CHECKS
76 | /* Optional sanity checker to call between isolated encoding steps. */
77 | DASM_FDEF int dasm_checkstep(Dst_DECL, int secmatch);
78 | #else
79 | #define dasm_checkstep(a, b) 0
80 | #endif
81 |
82 |
83 | #endif /* _DASM_PROTO_H */
84 |
--------------------------------------------------------------------------------
/dynasm/dasm_x64.lua:
--------------------------------------------------------------------------------
1 | ------------------------------------------------------------------------------
2 | -- DynASM x64 module.
3 | --
4 | -- Copyright (C) 2005-2025 Mike Pall. All rights reserved.
5 | -- See dynasm.lua for full copyright notice.
6 | ------------------------------------------------------------------------------
7 | -- This module just sets 64 bit mode for the combined x86/x64 module.
8 | -- All the interesting stuff is there.
9 | ------------------------------------------------------------------------------
10 |
11 | x64 = true -- Using a global is an ugly, but effective solution.
12 | return require("dasm_x86")
13 |
--------------------------------------------------------------------------------
/etc/luajit.1:
--------------------------------------------------------------------------------
1 | .TH luajit 1 "" "" "LuaJIT documentation"
2 | .SH NAME
3 | luajit \- Just-In-Time Compiler for the Lua Language
4 | \fB
5 | .SH SYNOPSIS
6 | .B luajit
7 | [\fIoptions\fR]... [\fIscript\fR [\fIargs\fR]...]
8 | .SH "WEB SITE"
9 | .IR https://luajit.org
10 | .SH DESCRIPTION
11 | .PP
12 | This is the command-line program to run Lua programs with \fBLuaJIT\fR.
13 | .PP
14 | \fBLuaJIT\fR is a just-in-time (JIT) compiler for the Lua language.
15 | The virtual machine (VM) is based on a fast interpreter combined with
16 | a trace compiler. It can significantly improve the performance of Lua programs.
17 | .PP
18 | \fBLuaJIT\fR is API\- and ABI-compatible with the VM of the standard
19 | Lua\ 5.1 interpreter. When embedding the VM into an application,
20 | the built library can be used as a drop-in replacement.
21 | .SH OPTIONS
22 | .TP
23 | .BI "\-e " chunk
24 | Run the given chunk of Lua code.
25 | .TP
26 | .BI "\-l " library
27 | Load the named library, just like \fBrequire("\fR\fIlibrary\fR\fB")\fR.
28 | .TP
29 | .BI "\-b " ...
30 | Save or list bytecode. Run without arguments to get help on options.
31 | .TP
32 | .BI "\-j " command
33 | Perform LuaJIT control command (optional space after \fB\-j\fR).
34 | .TP
35 | .BI "\-O" [opt]
36 | Control LuaJIT optimizations.
37 | .TP
38 | .B "\-i"
39 | Run in interactive mode.
40 | .TP
41 | .B "\-v"
42 | Show \fBLuaJIT\fR version.
43 | .TP
44 | .B "\-E"
45 | Ignore environment variables.
46 | .TP
47 | .B "\-\-"
48 | Stop processing options.
49 | .TP
50 | .B "\-"
51 | Read script from stdin instead.
52 | .PP
53 | After all options are processed, the given \fIscript\fR is run.
54 | The arguments are passed in the global \fIarg\fR table.
55 | .PP
56 | Interactive mode is only entered, if no \fIscript\fR and no \fB\-e\fR
57 | option is given. Interactive mode can be left with EOF (\fICtrl\-Z\fB).
58 | .SH EXAMPLES
59 | .TP
60 | luajit hello.lua world
61 |
62 | Prints "Hello world", assuming \fIhello.lua\fR contains:
63 | .br
64 | print("Hello", arg[1])
65 | .TP
66 | luajit \-e "local x=0; for i=1,1e9 do x=x+i end; print(x)"
67 |
68 | Calculates the sum of the numbers from 1 to 1000000000.
69 | .br
70 | And finishes in a reasonable amount of time, too.
71 | .TP
72 | luajit \-jv \-e "for i=1,10 do for j=1,10 do for k=1,100 do end end end"
73 |
74 | Runs some nested loops and shows the resulting traces.
75 | .SH COPYRIGHT
76 | .PP
77 | \fBLuaJIT\fR is Copyright \(co 2005-2025 Mike Pall.
78 | .br
79 | \fBLuaJIT\fR is open source software, released under the MIT license.
80 | .SH SEE ALSO
81 | .PP
82 | More details in the provided HTML docs or at:
83 | .IR https://luajit.org
84 | .br
85 | More about the Lua language can be found at:
86 | .IR https://lua.org/docs.html
87 | .PP
88 | lua(1)
89 |
--------------------------------------------------------------------------------
/etc/luajit.pc:
--------------------------------------------------------------------------------
1 | # Package information for LuaJIT to be used by pkg-config.
2 | majver=2
3 | minver=1
4 | relver=ROLLING
5 | version=${majver}.${minver}.${relver}
6 | abiver=5.1
7 |
8 | prefix=/usr/local
9 | multilib=lib
10 | exec_prefix=${prefix}
11 | libdir=${exec_prefix}/${multilib}
12 | libname=luajit-${abiver}
13 | includedir=${prefix}/include/luajit-${majver}.${minver}
14 |
15 | INSTALL_LMOD=${prefix}/share/lua/${abiver}
16 | INSTALL_CMOD=${prefix}/${multilib}/lua/${abiver}
17 |
18 | Name: LuaJIT
19 | Description: Just-in-time compiler for Lua
20 | URL: https://luajit.org
21 | Version: ${version}
22 | Requires:
23 | Libs: -L${libdir} -l${libname}
24 | Libs.private: -Wl,-E -lm -ldl
25 | Cflags: -I${includedir}
26 |
--------------------------------------------------------------------------------
/src/.gitignore:
--------------------------------------------------------------------------------
1 | luajit
2 | luajit.h
3 | luajit_relver.txt
4 | lj_bcdef.h
5 | lj_ffdef.h
6 | lj_libdef.h
7 | lj_recdef.h
8 | lj_folddef.h
9 | lj_vm.[sS]
10 |
--------------------------------------------------------------------------------
/src/host/.gitignore:
--------------------------------------------------------------------------------
1 | minilua
2 | buildvm
3 | buildvm_arch.h
4 |
--------------------------------------------------------------------------------
/src/host/README:
--------------------------------------------------------------------------------
1 | The files in this directory are only used during the build process of LuaJIT.
2 | For cross-compilation, they must be executed on the host, not on the target.
3 |
4 | These files should NOT be installed!
5 |
--------------------------------------------------------------------------------
/src/host/buildvm.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** LuaJIT VM builder.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _BUILDVM_H
7 | #define _BUILDVM_H
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #include "lj_def.h"
16 | #include "lj_arch.h"
17 |
18 | /* Hardcoded limits. Increase as needed. */
19 | #define BUILD_MAX_RELOC 200 /* Max. number of relocations. */
20 | #define BUILD_MAX_FOLD 4096 /* Max. number of fold rules. */
21 |
22 | /* Prefix for scanned library definitions. */
23 | #define LIBDEF_PREFIX "LJLIB_"
24 |
25 | /* Prefix for scanned fold definitions. */
26 | #define FOLDDEF_PREFIX "LJFOLD"
27 |
28 | /* Prefixes for generated labels. */
29 | #define LABEL_PREFIX "lj_"
30 | #define LABEL_PREFIX_BC LABEL_PREFIX "BC_"
31 | #define LABEL_PREFIX_FF LABEL_PREFIX "ff_"
32 | #define LABEL_PREFIX_CF LABEL_PREFIX "cf_"
33 | #define LABEL_PREFIX_FFH LABEL_PREFIX "ffh_"
34 | #define LABEL_PREFIX_LIBCF LABEL_PREFIX "lib_cf_"
35 | #define LABEL_PREFIX_LIBINIT LABEL_PREFIX "lib_init_"
36 |
37 | /* Forward declaration. */
38 | struct dasm_State;
39 |
40 | /* Build modes. */
41 | #define BUILDDEF(_) \
42 | _(elfasm) _(coffasm) _(machasm) _(peobj) _(raw) \
43 | _(bcdef) _(ffdef) _(libdef) _(recdef) _(vmdef) \
44 | _(folddef)
45 |
46 | typedef enum {
47 | #define BUILDENUM(name) BUILD_##name,
48 | BUILDDEF(BUILDENUM)
49 | #undef BUILDENUM
50 | BUILD__MAX
51 | } BuildMode;
52 |
53 | /* Code relocation. */
54 | typedef struct BuildReloc {
55 | int32_t ofs;
56 | int sym;
57 | int type;
58 | } BuildReloc;
59 |
60 | typedef struct BuildSym {
61 | const char *name;
62 | int32_t ofs;
63 | } BuildSym;
64 |
65 | /* Build context structure. */
66 | typedef struct BuildCtx {
67 | /* DynASM state pointer. Should be first member. */
68 | struct dasm_State *D;
69 | /* Parsed command line. */
70 | BuildMode mode;
71 | FILE *fp;
72 | const char *outname;
73 | char **args;
74 | /* Code and symbols generated by DynASM. */
75 | uint8_t *code;
76 | size_t codesz;
77 | int npc, nglob, nsym, nreloc, nrelocsym;
78 | void **glob;
79 | BuildSym *sym;
80 | const char **relocsym;
81 | int32_t *bc_ofs;
82 | const char *beginsym;
83 | /* Strings generated by DynASM. */
84 | const char *const *globnames;
85 | const char *const *extnames;
86 | const char *dasm_ident;
87 | const char *dasm_arch;
88 | /* Relocations. */
89 | BuildReloc reloc[BUILD_MAX_RELOC];
90 | } BuildCtx;
91 |
92 | extern void owrite(BuildCtx *ctx, const void *ptr, size_t sz);
93 | extern void emit_asm(BuildCtx *ctx);
94 | extern void emit_peobj(BuildCtx *ctx);
95 | extern void emit_lib(BuildCtx *ctx);
96 | extern void emit_fold(BuildCtx *ctx);
97 |
98 | extern const char *const bc_names[];
99 | extern const char *const ir_names[];
100 | extern const char *const irt_names[];
101 | extern const char *const irfpm_names[];
102 | extern const char *const irfield_names[];
103 | extern const char *const ircall_names[];
104 |
105 | #endif
106 |
--------------------------------------------------------------------------------
/src/host/buildvm_libbc.h:
--------------------------------------------------------------------------------
1 | /* This is a generated file. DO NOT EDIT! */
2 |
3 | static const int libbc_endian = 0;
4 |
5 | static const uint8_t libbc_code[] = {
6 | #if LJ_FR2
7 | /* math.deg */ 0,1,2,0,0,1,2,BC_MULVN,1,0,0,BC_RET1,1,2,0,241,135,158,166,3,
8 | 220,203,178,130,4,
9 | /* math.rad */ 0,1,2,0,0,1,2,BC_MULVN,1,0,0,BC_RET1,1,2,0,243,244,148,165,20,
10 | 198,190,199,252,3,
11 | /* string.len */ 0,1,2,0,0,0,3,BC_ISTYPE,0,5,0,BC_LEN,1,0,0,BC_RET1,1,2,0,
12 | /* table.foreachi */ 0,2,10,0,0,0,15,BC_ISTYPE,0,12,0,BC_ISTYPE,1,9,0,
13 | BC_KSHORT,2,1,0,BC_LEN,3,0,0,BC_KSHORT,4,1,0,BC_FORI,2,8,128,BC_MOV,6,1,0,
14 | BC_MOV,8,5,0,BC_TGETR,9,5,0,BC_CALL,6,3,2,BC_ISEQP,6,0,0,BC_JMP,7,1,128,
15 | BC_RET1,6,2,0,BC_FORL,2,248,127,BC_RET0,0,1,0,
16 | /* table.foreach */ 0,2,11,0,0,1,16,BC_ISTYPE,0,12,0,BC_ISTYPE,1,9,0,BC_KPRI,
17 | 2,0,0,BC_MOV,3,0,0,BC_KNUM,4,0,0,BC_JMP,5,7,128,BC_MOV,7,1,0,BC_MOV,9,5,0,
18 | BC_MOV,10,6,0,BC_CALL,7,3,2,BC_ISEQP,7,0,0,BC_JMP,8,1,128,BC_RET1,7,2,0,
19 | BC_ITERN,5,3,3,BC_ITERL,5,247,127,BC_RET0,0,1,0,1,255,255,249,255,15,
20 | /* table.getn */ 0,1,2,0,0,0,3,BC_ISTYPE,0,12,0,BC_LEN,1,0,0,BC_RET1,1,2,0,
21 | /* table.remove */ 0,2,10,0,0,2,30,BC_ISTYPE,0,12,0,BC_LEN,2,0,0,BC_ISNEP,1,0,
22 | 0,BC_JMP,3,7,128,BC_ISEQN,2,0,0,BC_JMP,3,23,128,BC_TGETR,3,2,0,BC_KPRI,4,0,0,
23 | BC_TSETR,4,2,0,BC_RET1,3,2,0,BC_JMP,3,18,128,BC_ISTYPE,1,14,0,BC_KSHORT,3,1,0,
24 | BC_ISGT,3,1,0,BC_JMP,3,14,128,BC_ISGT,1,2,0,BC_JMP,3,12,128,BC_TGETR,3,1,0,
25 | BC_ADDVN,4,1,1,BC_MOV,5,2,0,BC_KSHORT,6,1,0,BC_FORI,4,4,128,BC_SUBVN,8,1,7,
26 | BC_TGETR,9,7,0,BC_TSETR,9,8,0,BC_FORL,4,252,127,BC_KPRI,4,0,0,BC_TSETR,4,2,0,
27 | BC_RET1,3,2,0,BC_RET0,0,1,0,0,2,
28 | /* table.move */ 0,5,12,0,0,0,35,BC_ISTYPE,0,12,0,BC_ISTYPE,1,14,0,BC_ISTYPE,
29 | 2,14,0,BC_ISTYPE,3,14,0,BC_ISNEP,4,0,0,BC_JMP,5,1,128,BC_MOV,4,0,0,BC_ISTYPE,
30 | 4,12,0,BC_ISGT,1,2,0,BC_JMP,5,24,128,BC_SUBVV,5,1,3,BC_ISLT,2,3,0,BC_JMP,6,4,
31 | 128,BC_ISLE,3,1,0,BC_JMP,6,2,128,BC_ISEQV,4,0,0,BC_JMP,6,9,128,BC_MOV,6,1,0,
32 | BC_MOV,7,2,0,BC_KSHORT,8,1,0,BC_FORI,6,4,128,BC_ADDVV,10,5,9,BC_TGETR,11,9,0,
33 | BC_TSETR,11,10,4,BC_FORL,6,252,127,BC_JMP,6,8,128,BC_MOV,6,2,0,BC_MOV,7,1,0,
34 | BC_KSHORT,8,255,255,BC_FORI,6,4,128,BC_ADDVV,10,5,9,BC_TGETR,11,9,0,BC_TSETR,
35 | 11,10,4,BC_FORL,6,252,127,BC_RET1,4,2,0,
36 | #else
37 | /* math.deg */ 0,1,2,0,0,1,2,BC_MULVN,1,0,0,BC_RET1,1,2,0,241,135,158,166,3,
38 | 220,203,178,130,4,
39 | /* math.rad */ 0,1,2,0,0,1,2,BC_MULVN,1,0,0,BC_RET1,1,2,0,243,244,148,165,20,
40 | 198,190,199,252,3,
41 | /* string.len */ 0,1,2,0,0,0,3,BC_ISTYPE,0,5,0,BC_LEN,1,0,0,BC_RET1,1,2,0,
42 | /* table.foreachi */ 0,2,9,0,0,0,15,BC_ISTYPE,0,12,0,BC_ISTYPE,1,9,0,
43 | BC_KSHORT,2,1,0,BC_LEN,3,0,0,BC_KSHORT,4,1,0,BC_FORI,2,8,128,BC_MOV,6,1,0,
44 | BC_MOV,7,5,0,BC_TGETR,8,5,0,BC_CALL,6,3,2,BC_ISEQP,6,0,0,BC_JMP,7,1,128,
45 | BC_RET1,6,2,0,BC_FORL,2,248,127,BC_RET0,0,1,0,
46 | /* table.foreach */ 0,2,10,0,0,1,16,BC_ISTYPE,0,12,0,BC_ISTYPE,1,9,0,BC_KPRI,
47 | 2,0,0,BC_MOV,3,0,0,BC_KNUM,4,0,0,BC_JMP,5,7,128,BC_MOV,7,1,0,BC_MOV,8,5,0,
48 | BC_MOV,9,6,0,BC_CALL,7,3,2,BC_ISEQP,7,0,0,BC_JMP,8,1,128,BC_RET1,7,2,0,
49 | BC_ITERN,5,3,3,BC_ITERL,5,247,127,BC_RET0,0,1,0,1,255,255,249,255,15,
50 | /* table.getn */ 0,1,2,0,0,0,3,BC_ISTYPE,0,12,0,BC_LEN,1,0,0,BC_RET1,1,2,0,
51 | /* table.remove */ 0,2,10,0,0,2,30,BC_ISTYPE,0,12,0,BC_LEN,2,0,0,BC_ISNEP,1,0,
52 | 0,BC_JMP,3,7,128,BC_ISEQN,2,0,0,BC_JMP,3,23,128,BC_TGETR,3,2,0,BC_KPRI,4,0,0,
53 | BC_TSETR,4,2,0,BC_RET1,3,2,0,BC_JMP,3,18,128,BC_ISTYPE,1,14,0,BC_KSHORT,3,1,0,
54 | BC_ISGT,3,1,0,BC_JMP,3,14,128,BC_ISGT,1,2,0,BC_JMP,3,12,128,BC_TGETR,3,1,0,
55 | BC_ADDVN,4,1,1,BC_MOV,5,2,0,BC_KSHORT,6,1,0,BC_FORI,4,4,128,BC_SUBVN,8,1,7,
56 | BC_TGETR,9,7,0,BC_TSETR,9,8,0,BC_FORL,4,252,127,BC_KPRI,4,0,0,BC_TSETR,4,2,0,
57 | BC_RET1,3,2,0,BC_RET0,0,1,0,0,2,
58 | /* table.move */ 0,5,12,0,0,0,35,BC_ISTYPE,0,12,0,BC_ISTYPE,1,14,0,BC_ISTYPE,
59 | 2,14,0,BC_ISTYPE,3,14,0,BC_ISNEP,4,0,0,BC_JMP,5,1,128,BC_MOV,4,0,0,BC_ISTYPE,
60 | 4,12,0,BC_ISGT,1,2,0,BC_JMP,5,24,128,BC_SUBVV,5,1,3,BC_ISLT,2,3,0,BC_JMP,6,4,
61 | 128,BC_ISLE,3,1,0,BC_JMP,6,2,128,BC_ISEQV,4,0,0,BC_JMP,6,9,128,BC_MOV,6,1,0,
62 | BC_MOV,7,2,0,BC_KSHORT,8,1,0,BC_FORI,6,4,128,BC_ADDVV,10,5,9,BC_TGETR,11,9,0,
63 | BC_TSETR,11,10,4,BC_FORL,6,252,127,BC_JMP,6,8,128,BC_MOV,6,2,0,BC_MOV,7,1,0,
64 | BC_KSHORT,8,255,255,BC_FORI,6,4,128,BC_ADDVV,10,5,9,BC_TGETR,11,9,0,BC_TSETR,
65 | 11,10,4,BC_FORL,6,252,127,BC_RET1,4,2,0,
66 | #endif
67 | 0
68 | };
69 |
70 | static const struct { const char *name; int ofs; } libbc_map[] = {
71 | {"math_deg",0},
72 | {"math_rad",25},
73 | {"string_len",50},
74 | {"table_foreachi",69},
75 | {"table_foreach",136},
76 | {"table_getn",213},
77 | {"table_remove",232},
78 | {"table_move",361},
79 | {NULL,508}
80 | };
81 |
82 |
--------------------------------------------------------------------------------
/src/host/genversion.lua:
--------------------------------------------------------------------------------
1 | ----------------------------------------------------------------------------
2 | -- Lua script to embed the rolling release version in luajit.h.
3 | ----------------------------------------------------------------------------
4 | -- Copyright (C) 2005-2025 Mike Pall. All rights reserved.
5 | -- Released under the MIT license. See Copyright Notice in luajit.h
6 | ----------------------------------------------------------------------------
7 |
8 | local arg = {...}
9 | local FILE_ROLLING_H = arg[1] or "luajit_rolling.h"
10 | local FILE_RELVER_TXT = arg[2] or "luajit_relver.txt"
11 | local FILE_LUAJIT_H = arg[3] or "luajit.h"
12 |
13 | local function file_read(file)
14 | local fp = assert(io.open(file, "rb"), "run from the wrong directory")
15 | local data = assert(fp:read("*a"))
16 | fp:close()
17 | return data
18 | end
19 |
20 | local function file_write_mod(file, data)
21 | local fp = io.open(file, "rb")
22 | if fp then
23 | local odata = assert(fp:read("*a"))
24 | fp:close()
25 | if odata == data then return end
26 | end
27 | fp = assert(io.open(file, "wb"))
28 | assert(fp:write(data))
29 | assert(fp:close())
30 | end
31 |
32 | local text = file_read(FILE_ROLLING_H):gsub("#error.-\n", "")
33 | local relver = file_read(FILE_RELVER_TXT):match("(%d+)")
34 |
35 | if relver then
36 | text = text:gsub("ROLLING", relver)
37 | else
38 | io.stderr:write([[
39 | **** WARNING Cannot determine rolling release version from git log.
40 | **** WARNING The 'git' command must be available during the build.
41 | ]])
42 | file_write_mod(FILE_RELVER_TXT, "ROLLING\n") -- Fallback for install target.
43 | end
44 |
45 | file_write_mod(FILE_LUAJIT_H, text)
46 |
--------------------------------------------------------------------------------
/src/jit/.gitignore:
--------------------------------------------------------------------------------
1 | vmdef.lua
2 |
--------------------------------------------------------------------------------
/src/jit/dis_arm64be.lua:
--------------------------------------------------------------------------------
1 | ----------------------------------------------------------------------------
2 | -- LuaJIT ARM64BE disassembler wrapper module.
3 | --
4 | -- Copyright (C) 2005-2025 Mike Pall. All rights reserved.
5 | -- Released under the MIT license. See Copyright Notice in luajit.h
6 | ----------------------------------------------------------------------------
7 | -- ARM64 instructions are always little-endian. So just forward to the
8 | -- common ARM64 disassembler module. All the interesting stuff is there.
9 | ------------------------------------------------------------------------------
10 |
11 | return require((string.match(..., ".*%.") or "").."dis_arm64")
12 |
13 |
--------------------------------------------------------------------------------
/src/jit/dis_mips64.lua:
--------------------------------------------------------------------------------
1 | ----------------------------------------------------------------------------
2 | -- LuaJIT MIPS64 disassembler wrapper module.
3 | --
4 | -- Copyright (C) 2005-2025 Mike Pall. All rights reserved.
5 | -- Released under the MIT license. See Copyright Notice in luajit.h
6 | ----------------------------------------------------------------------------
7 | -- This module just exports the big-endian functions from the
8 | -- MIPS disassembler module. All the interesting stuff is there.
9 | ------------------------------------------------------------------------------
10 |
11 | local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
12 | return {
13 | create = dis_mips.create,
14 | disass = dis_mips.disass,
15 | regname = dis_mips.regname
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/src/jit/dis_mips64el.lua:
--------------------------------------------------------------------------------
1 | ----------------------------------------------------------------------------
2 | -- LuaJIT MIPS64EL disassembler wrapper module.
3 | --
4 | -- Copyright (C) 2005-2025 Mike Pall. All rights reserved.
5 | -- Released under the MIT license. See Copyright Notice in luajit.h
6 | ----------------------------------------------------------------------------
7 | -- This module just exports the little-endian functions from the
8 | -- MIPS disassembler module. All the interesting stuff is there.
9 | ------------------------------------------------------------------------------
10 |
11 | local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
12 | return {
13 | create = dis_mips.create_el,
14 | disass = dis_mips.disass_el,
15 | regname = dis_mips.regname
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/src/jit/dis_mips64r6.lua:
--------------------------------------------------------------------------------
1 | ----------------------------------------------------------------------------
2 | -- LuaJIT MIPS64R6 disassembler wrapper module.
3 | --
4 | -- Copyright (C) 2005-2025 Mike Pall. All rights reserved.
5 | -- Released under the MIT license. See Copyright Notice in luajit.h
6 | ----------------------------------------------------------------------------
7 | -- This module just exports the r6 big-endian functions from the
8 | -- MIPS disassembler module. All the interesting stuff is there.
9 | ------------------------------------------------------------------------------
10 |
11 | local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
12 | return {
13 | create = dis_mips.create_r6,
14 | disass = dis_mips.disass_r6,
15 | regname = dis_mips.regname
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/src/jit/dis_mips64r6el.lua:
--------------------------------------------------------------------------------
1 | ----------------------------------------------------------------------------
2 | -- LuaJIT MIPS64R6EL disassembler wrapper module.
3 | --
4 | -- Copyright (C) 2005-2025 Mike Pall. All rights reserved.
5 | -- Released under the MIT license. See Copyright Notice in luajit.h
6 | ----------------------------------------------------------------------------
7 | -- This module just exports the r6 little-endian functions from the
8 | -- MIPS disassembler module. All the interesting stuff is there.
9 | ------------------------------------------------------------------------------
10 |
11 | local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
12 | return {
13 | create = dis_mips.create_r6_el,
14 | disass = dis_mips.disass_r6_el,
15 | regname = dis_mips.regname
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/src/jit/dis_mipsel.lua:
--------------------------------------------------------------------------------
1 | ----------------------------------------------------------------------------
2 | -- LuaJIT MIPSEL disassembler wrapper module.
3 | --
4 | -- Copyright (C) 2005-2025 Mike Pall. All rights reserved.
5 | -- Released under the MIT license. See Copyright Notice in luajit.h
6 | ----------------------------------------------------------------------------
7 | -- This module just exports the little-endian functions from the
8 | -- MIPS disassembler module. All the interesting stuff is there.
9 | ------------------------------------------------------------------------------
10 |
11 | local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
12 | return {
13 | create = dis_mips.create_el,
14 | disass = dis_mips.disass_el,
15 | regname = dis_mips.regname
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/src/jit/dis_x64.lua:
--------------------------------------------------------------------------------
1 | ----------------------------------------------------------------------------
2 | -- LuaJIT x64 disassembler wrapper module.
3 | --
4 | -- Copyright (C) 2005-2025 Mike Pall. All rights reserved.
5 | -- Released under the MIT license. See Copyright Notice in luajit.h
6 | ----------------------------------------------------------------------------
7 | -- This module just exports the 64 bit functions from the combined
8 | -- x86/x64 disassembler module. All the interesting stuff is there.
9 | ------------------------------------------------------------------------------
10 |
11 | local dis_x86 = require((string.match(..., ".*%.") or "").."dis_x86")
12 | return {
13 | create = dis_x86.create64,
14 | disass = dis_x86.disass64,
15 | regname = dis_x86.regname64
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/src/jit/zone.lua:
--------------------------------------------------------------------------------
1 | ----------------------------------------------------------------------------
2 | -- LuaJIT profiler zones.
3 | --
4 | -- Copyright (C) 2005-2025 Mike Pall. All rights reserved.
5 | -- Released under the MIT license. See Copyright Notice in luajit.h
6 | ----------------------------------------------------------------------------
7 | --
8 | -- This module implements a simple hierarchical zone model.
9 | --
10 | -- Example usage:
11 | --
12 | -- local zone = require("jit.zone")
13 | -- zone("AI")
14 | -- ...
15 | -- zone("A*")
16 | -- ...
17 | -- print(zone:get()) --> "A*"
18 | -- ...
19 | -- zone()
20 | -- ...
21 | -- print(zone:get()) --> "AI"
22 | -- ...
23 | -- zone()
24 | --
25 | ----------------------------------------------------------------------------
26 |
27 | local remove = table.remove
28 |
29 | return setmetatable({
30 | flush = function(t)
31 | for i=#t,1,-1 do t[i] = nil end
32 | end,
33 | get = function(t)
34 | return t[#t]
35 | end
36 | }, {
37 | __call = function(t, zone)
38 | if zone then
39 | t[#t+1] = zone
40 | else
41 | return (assert(remove(t), "empty zone stack"))
42 | end
43 | end
44 | })
45 |
46 |
--------------------------------------------------------------------------------
/src/lib_bit.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Bit manipulation library.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #define lib_bit_c
7 | #define LUA_LIB
8 |
9 | #include "lua.h"
10 | #include "lauxlib.h"
11 | #include "lualib.h"
12 |
13 | #include "lj_obj.h"
14 | #include "lj_err.h"
15 | #include "lj_buf.h"
16 | #include "lj_strscan.h"
17 | #include "lj_strfmt.h"
18 | #if LJ_HASFFI
19 | #include "lj_ctype.h"
20 | #include "lj_cdata.h"
21 | #include "lj_cconv.h"
22 | #include "lj_carith.h"
23 | #endif
24 | #include "lj_ff.h"
25 | #include "lj_lib.h"
26 |
27 | /* ------------------------------------------------------------------------ */
28 |
29 | #define LJLIB_MODULE_bit
30 |
31 | #if LJ_HASFFI
32 | static int bit_result64(lua_State *L, CTypeID id, uint64_t x)
33 | {
34 | GCcdata *cd = lj_cdata_new_(L, id, 8);
35 | *(uint64_t *)cdataptr(cd) = x;
36 | setcdataV(L, L->base-1-LJ_FR2, cd);
37 | return FFH_RES(1);
38 | }
39 | #else
40 | static int32_t bit_checkbit(lua_State *L, int narg)
41 | {
42 | TValue *o = L->base + narg-1;
43 | if (!(o < L->top && lj_strscan_numberobj(o)))
44 | lj_err_argt(L, narg, LUA_TNUMBER);
45 | if (LJ_LIKELY(tvisint(o))) {
46 | return intV(o);
47 | } else {
48 | int32_t i = lj_num2bit(numV(o));
49 | if (LJ_DUALNUM) setintV(o, i);
50 | return i;
51 | }
52 | }
53 | #endif
54 |
55 | LJLIB_ASM(bit_tobit) LJLIB_REC(bit_tobit)
56 | {
57 | #if LJ_HASFFI
58 | CTypeID id = 0;
59 | setintV(L->base-1-LJ_FR2, (int32_t)lj_carith_check64(L, 1, &id));
60 | return FFH_RES(1);
61 | #else
62 | lj_lib_checknumber(L, 1);
63 | return FFH_RETRY;
64 | #endif
65 | }
66 |
67 | LJLIB_ASM(bit_bnot) LJLIB_REC(bit_unary IR_BNOT)
68 | {
69 | #if LJ_HASFFI
70 | CTypeID id = 0;
71 | uint64_t x = lj_carith_check64(L, 1, &id);
72 | return id ? bit_result64(L, id, ~x) : FFH_RETRY;
73 | #else
74 | lj_lib_checknumber(L, 1);
75 | return FFH_RETRY;
76 | #endif
77 | }
78 |
79 | LJLIB_ASM(bit_bswap) LJLIB_REC(bit_unary IR_BSWAP)
80 | {
81 | #if LJ_HASFFI
82 | CTypeID id = 0;
83 | uint64_t x = lj_carith_check64(L, 1, &id);
84 | return id ? bit_result64(L, id, lj_bswap64(x)) : FFH_RETRY;
85 | #else
86 | lj_lib_checknumber(L, 1);
87 | return FFH_RETRY;
88 | #endif
89 | }
90 |
91 | LJLIB_ASM(bit_lshift) LJLIB_REC(bit_shift IR_BSHL)
92 | {
93 | #if LJ_HASFFI
94 | CTypeID id = 0, id2 = 0;
95 | uint64_t x = lj_carith_check64(L, 1, &id);
96 | int32_t sh = (int32_t)lj_carith_check64(L, 2, &id2);
97 | if (id) {
98 | x = lj_carith_shift64(x, sh, curr_func(L)->c.ffid - (int)FF_bit_lshift);
99 | return bit_result64(L, id, x);
100 | }
101 | setintV(L->base+1, sh);
102 | return FFH_RETRY;
103 | #else
104 | lj_lib_checknumber(L, 1);
105 | bit_checkbit(L, 2);
106 | return FFH_RETRY;
107 | #endif
108 | }
109 | LJLIB_ASM_(bit_rshift) LJLIB_REC(bit_shift IR_BSHR)
110 | LJLIB_ASM_(bit_arshift) LJLIB_REC(bit_shift IR_BSAR)
111 | LJLIB_ASM_(bit_rol) LJLIB_REC(bit_shift IR_BROL)
112 | LJLIB_ASM_(bit_ror) LJLIB_REC(bit_shift IR_BROR)
113 |
114 | LJLIB_ASM(bit_band) LJLIB_REC(bit_nary IR_BAND)
115 | {
116 | #if LJ_HASFFI
117 | CTypeID id = 0;
118 | TValue *o = L->base, *top = L->top;
119 | int i = 0;
120 | do { lj_carith_check64(L, ++i, &id); } while (++o < top);
121 | if (id) {
122 | CTState *cts = ctype_cts(L);
123 | CType *ct = ctype_get(cts, id);
124 | int op = curr_func(L)->c.ffid - (int)FF_bit_bor;
125 | uint64_t x, y = op >= 0 ? 0 : ~(uint64_t)0;
126 | o = L->base;
127 | do {
128 | lj_cconv_ct_tv(cts, ct, (uint8_t *)&x, o, 0);
129 | if (op < 0) y &= x; else if (op == 0) y |= x; else y ^= x;
130 | } while (++o < top);
131 | return bit_result64(L, id, y);
132 | }
133 | return FFH_RETRY;
134 | #else
135 | int i = 0;
136 | do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top);
137 | return FFH_RETRY;
138 | #endif
139 | }
140 | LJLIB_ASM_(bit_bor) LJLIB_REC(bit_nary IR_BOR)
141 | LJLIB_ASM_(bit_bxor) LJLIB_REC(bit_nary IR_BXOR)
142 |
143 | /* ------------------------------------------------------------------------ */
144 |
145 | LJLIB_CF(bit_tohex) LJLIB_REC(.)
146 | {
147 | #if LJ_HASFFI
148 | CTypeID id = 0, id2 = 0;
149 | uint64_t b = lj_carith_check64(L, 1, &id);
150 | int32_t n = L->base+1>=L->top ? (id ? 16 : 8) :
151 | (int32_t)lj_carith_check64(L, 2, &id2);
152 | #else
153 | uint32_t b = (uint32_t)bit_checkbit(L, 1);
154 | int32_t n = L->base+1>=L->top ? 8 : bit_checkbit(L, 2);
155 | #endif
156 | SBuf *sb = lj_buf_tmp_(L);
157 | SFormat sf = (STRFMT_UINT|STRFMT_T_HEX);
158 | if (n < 0) { n = (int32_t)(~(uint32_t)n+1u); sf |= STRFMT_F_UPPER; }
159 | if ((uint32_t)n > 254) n = 254;
160 | sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
161 | #if LJ_HASFFI
162 | if (n < 16) b &= ((uint64_t)1 << 4*n)-1;
163 | #else
164 | if (n < 8) b &= (1u << 4*n)-1;
165 | #endif
166 | sb = lj_strfmt_putfxint(sb, sf, b);
167 | setstrV(L, L->top-1, lj_buf_str(L, sb));
168 | lj_gc_check(L);
169 | return 1;
170 | }
171 |
172 | /* ------------------------------------------------------------------------ */
173 |
174 | #include "lj_libdef.h"
175 |
176 | LUALIB_API int luaopen_bit(lua_State *L)
177 | {
178 | LJ_LIB_REG(L, LUA_BITLIBNAME, bit);
179 | return 1;
180 | }
181 |
182 |
--------------------------------------------------------------------------------
/src/lib_init.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Library initialization.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | **
5 | ** Major parts taken verbatim from the Lua interpreter.
6 | ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7 | */
8 |
9 | #define lib_init_c
10 | #define LUA_LIB
11 |
12 | #include "lua.h"
13 | #include "lauxlib.h"
14 | #include "lualib.h"
15 |
16 | #include "lj_arch.h"
17 |
18 | static const luaL_Reg lj_lib_load[] = {
19 | { "", luaopen_base },
20 | { LUA_LOADLIBNAME, luaopen_package },
21 | { LUA_TABLIBNAME, luaopen_table },
22 | { LUA_IOLIBNAME, luaopen_io },
23 | { LUA_OSLIBNAME, luaopen_os },
24 | { LUA_STRLIBNAME, luaopen_string },
25 | { LUA_MATHLIBNAME, luaopen_math },
26 | { LUA_DBLIBNAME, luaopen_debug },
27 | { LUA_BITLIBNAME, luaopen_bit },
28 | { LUA_JITLIBNAME, luaopen_jit },
29 | { NULL, NULL }
30 | };
31 |
32 | static const luaL_Reg lj_lib_preload[] = {
33 | #if LJ_HASFFI
34 | { LUA_FFILIBNAME, luaopen_ffi },
35 | #endif
36 | { NULL, NULL }
37 | };
38 |
39 | LUALIB_API void luaL_openlibs(lua_State *L)
40 | {
41 | const luaL_Reg *lib;
42 | for (lib = lj_lib_load; lib->func; lib++) {
43 | lua_pushcfunction(L, lib->func);
44 | lua_pushstring(L, lib->name);
45 | lua_call(L, 1, 0);
46 | }
47 | luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD",
48 | sizeof(lj_lib_preload)/sizeof(lj_lib_preload[0])-1);
49 | for (lib = lj_lib_preload; lib->func; lib++) {
50 | lua_pushcfunction(L, lib->func);
51 | lua_setfield(L, -2, lib->name);
52 | }
53 | lua_pop(L, 1);
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/src/lj_alloc.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Bundled memory allocator.
3 | ** Donated to the public domain.
4 | */
5 |
6 | #ifndef _LJ_ALLOC_H
7 | #define _LJ_ALLOC_H
8 |
9 | #include "lj_def.h"
10 |
11 | #ifndef LUAJIT_USE_SYSMALLOC
12 | LJ_FUNC void *lj_alloc_create(PRNGState *rs);
13 | LJ_FUNC void lj_alloc_setprng(void *msp, PRNGState *rs);
14 | LJ_FUNC void lj_alloc_destroy(void *msp);
15 | LJ_FUNC void *lj_alloc_f(void *msp, void *ptr, size_t osize, size_t nsize);
16 | #endif
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/src/lj_asm.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** IR assembler (SSA IR -> machine code).
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_ASM_H
7 | #define _LJ_ASM_H
8 |
9 | #include "lj_jit.h"
10 |
11 | #if LJ_HASJIT
12 | LJ_FUNC void lj_asm_trace(jit_State *J, GCtrace *T);
13 | LJ_FUNC void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno,
14 | MCode *target);
15 | #endif
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/src/lj_assert.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Internal assertions.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #define lj_assert_c
7 | #define LUA_CORE
8 |
9 | #if defined(LUA_USE_ASSERT) || defined(LUA_USE_APICHECK)
10 |
11 | #include
12 |
13 | #include "lj_obj.h"
14 |
15 | void lj_assert_fail(global_State *g, const char *file, int line,
16 | const char *func, const char *fmt, ...)
17 | {
18 | va_list argp;
19 | va_start(argp, fmt);
20 | fprintf(stderr, "LuaJIT ASSERT %s:%d: %s: ", file, line, func);
21 | vfprintf(stderr, fmt, argp);
22 | fputc('\n', stderr);
23 | va_end(argp);
24 | UNUSED(g); /* May be NULL. TODO: optionally dump state. */
25 | abort();
26 | }
27 |
28 | #endif
29 |
--------------------------------------------------------------------------------
/src/lj_bc.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Bytecode instruction modes.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #define lj_bc_c
7 | #define LUA_CORE
8 |
9 | #include "lj_obj.h"
10 | #include "lj_bc.h"
11 |
12 | /* Bytecode offsets and bytecode instruction modes. */
13 | #include "lj_bcdef.h"
14 |
15 |
--------------------------------------------------------------------------------
/src/lj_bcdump.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Bytecode dump definitions.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_BCDUMP_H
7 | #define _LJ_BCDUMP_H
8 |
9 | #include "lj_obj.h"
10 | #include "lj_lex.h"
11 |
12 | /* -- Bytecode dump format ------------------------------------------------ */
13 |
14 | /*
15 | ** dump = header proto+ 0U
16 | ** header = ESC 'L' 'J' versionB flagsU [namelenU nameB*]
17 | ** proto = lengthU pdata
18 | ** pdata = phead bcinsW* uvdataH* kgc* knum* [debugB*]
19 | ** phead = flagsB numparamsB framesizeB numuvB numkgcU numknU numbcU
20 | ** [debuglenU [firstlineU numlineU]]
21 | ** kgc = kgctypeU { ktab | (loU hiU) | (rloU rhiU iloU ihiU) | strB* }
22 | ** knum = intU0 | (loU1 hiU)
23 | ** ktab = narrayU nhashU karray* khash*
24 | ** karray = ktabk
25 | ** khash = ktabk ktabk
26 | ** ktabk = ktabtypeU { intU | (loU hiU) | strB* }
27 | **
28 | ** B = 8 bit, H = 16 bit, W = 32 bit, U = ULEB128 of W, U0/U1 = ULEB128 of W+1
29 | */
30 |
31 | /* Bytecode dump header. */
32 | #define BCDUMP_HEAD1 0x1b
33 | #define BCDUMP_HEAD2 0x4c
34 | #define BCDUMP_HEAD3 0x4a
35 |
36 | /* If you perform *any* kind of private modifications to the bytecode itself
37 | ** or to the dump format, you *must* set BCDUMP_VERSION to 0x80 or higher.
38 | */
39 | #define BCDUMP_VERSION 2
40 |
41 | /* Compatibility flags. */
42 | #define BCDUMP_F_BE 0x01
43 | #define BCDUMP_F_STRIP 0x02
44 | #define BCDUMP_F_FFI 0x04
45 | #define BCDUMP_F_FR2 0x08
46 |
47 | #define BCDUMP_F_KNOWN (BCDUMP_F_FR2*2-1)
48 |
49 | #define BCDUMP_F_DETERMINISTIC 0x80000000
50 |
51 | /* Type codes for the GC constants of a prototype. Plus length for strings. */
52 | enum {
53 | BCDUMP_KGC_CHILD, BCDUMP_KGC_TAB, BCDUMP_KGC_I64, BCDUMP_KGC_U64,
54 | BCDUMP_KGC_COMPLEX, BCDUMP_KGC_STR
55 | };
56 |
57 | /* Type codes for the keys/values of a constant table. */
58 | enum {
59 | BCDUMP_KTAB_NIL, BCDUMP_KTAB_FALSE, BCDUMP_KTAB_TRUE,
60 | BCDUMP_KTAB_INT, BCDUMP_KTAB_NUM, BCDUMP_KTAB_STR
61 | };
62 |
63 | /* -- Bytecode reader/writer ---------------------------------------------- */
64 |
65 | LJ_FUNC int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer,
66 | void *data, uint32_t flags);
67 | LJ_FUNC GCproto *lj_bcread_proto(LexState *ls);
68 | LJ_FUNC GCproto *lj_bcread(LexState *ls);
69 |
70 | #endif
71 |
--------------------------------------------------------------------------------
/src/lj_carith.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** C data arithmetic.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_CARITH_H
7 | #define _LJ_CARITH_H
8 |
9 | #include "lj_obj.h"
10 |
11 | #if LJ_HASFFI
12 |
13 | LJ_FUNC int lj_carith_op(lua_State *L, MMS mm);
14 |
15 | #if LJ_32
16 | LJ_FUNC uint64_t lj_carith_shl64(uint64_t x, int32_t sh);
17 | LJ_FUNC uint64_t lj_carith_shr64(uint64_t x, int32_t sh);
18 | LJ_FUNC uint64_t lj_carith_sar64(uint64_t x, int32_t sh);
19 | LJ_FUNC uint64_t lj_carith_rol64(uint64_t x, int32_t sh);
20 | LJ_FUNC uint64_t lj_carith_ror64(uint64_t x, int32_t sh);
21 | #endif
22 | LJ_FUNC uint64_t lj_carith_shift64(uint64_t x, int32_t sh, int op);
23 | LJ_FUNC uint64_t lj_carith_check64(lua_State *L, int narg, CTypeID *id);
24 |
25 | #if LJ_32 && LJ_HASJIT
26 | LJ_FUNC int64_t lj_carith_mul64(int64_t x, int64_t k);
27 | #endif
28 | LJ_FUNC uint64_t lj_carith_divu64(uint64_t a, uint64_t b);
29 | LJ_FUNC int64_t lj_carith_divi64(int64_t a, int64_t b);
30 | LJ_FUNC uint64_t lj_carith_modu64(uint64_t a, uint64_t b);
31 | LJ_FUNC int64_t lj_carith_modi64(int64_t a, int64_t b);
32 | LJ_FUNC uint64_t lj_carith_powu64(uint64_t x, uint64_t k);
33 | LJ_FUNC int64_t lj_carith_powi64(int64_t x, int64_t k);
34 |
35 | #endif
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/src/lj_ccallback.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** FFI C callback handling.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_CCALLBACK_H
7 | #define _LJ_CCALLBACK_H
8 |
9 | #include "lj_obj.h"
10 | #include "lj_ctype.h"
11 |
12 | #if LJ_HASFFI
13 |
14 | /* Really belongs to lj_vm.h. */
15 | LJ_ASMF void lj_vm_ffi_callback(void);
16 |
17 | LJ_FUNC MSize lj_ccallback_ptr2slot(CTState *cts, void *p);
18 | LJ_FUNCA lua_State * LJ_FASTCALL lj_ccallback_enter(CTState *cts, void *cf);
19 | LJ_FUNCA void LJ_FASTCALL lj_ccallback_leave(CTState *cts, TValue *o);
20 | LJ_FUNC void *lj_ccallback_new(CTState *cts, CType *ct, GCfunc *fn);
21 | LJ_FUNC void lj_ccallback_mcode_free(CTState *cts);
22 |
23 | #endif
24 |
25 | #endif
26 |
--------------------------------------------------------------------------------
/src/lj_cconv.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** C type conversions.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_CCONV_H
7 | #define _LJ_CCONV_H
8 |
9 | #include "lj_obj.h"
10 | #include "lj_ctype.h"
11 |
12 | #if LJ_HASFFI
13 |
14 | /* Compressed C type index. ORDER CCX. */
15 | enum {
16 | CCX_B, /* Bool. */
17 | CCX_I, /* Integer. */
18 | CCX_F, /* Floating-point number. */
19 | CCX_C, /* Complex. */
20 | CCX_V, /* Vector. */
21 | CCX_P, /* Pointer. */
22 | CCX_A, /* Refarray. */
23 | CCX_S /* Struct/union. */
24 | };
25 |
26 | /* Convert C type info to compressed C type index. ORDER CT. ORDER CCX. */
27 | static LJ_AINLINE uint32_t cconv_idx(CTInfo info)
28 | {
29 | uint32_t idx = ((info >> 26) & 15u); /* Dispatch bits. */
30 | lj_assertX(ctype_type(info) <= CT_MAYCONVERT,
31 | "cannot convert ctype %08x", info);
32 | #if LJ_64
33 | idx = ((uint32_t)(U64x(f436fff5,fff7f021) >> 4*idx) & 15u);
34 | #else
35 | idx = (((idx < 8 ? 0xfff7f021u : 0xf436fff5) >> 4*(idx & 7u)) & 15u);
36 | #endif
37 | lj_assertX(idx < 8, "cannot convert ctype %08x", info);
38 | return idx;
39 | }
40 |
41 | #define cconv_idx2(dinfo, sinfo) \
42 | ((cconv_idx((dinfo)) << 3) + cconv_idx((sinfo)))
43 |
44 | #define CCX(dst, src) ((CCX_##dst << 3) + CCX_##src)
45 |
46 | /* Conversion flags. */
47 | #define CCF_CAST 0x00000001u
48 | #define CCF_FROMTV 0x00000002u
49 | #define CCF_SAME 0x00000004u
50 | #define CCF_IGNQUAL 0x00000008u
51 |
52 | #define CCF_ARG_SHIFT 8
53 | #define CCF_ARG(n) ((n) << CCF_ARG_SHIFT)
54 | #define CCF_GETARG(f) ((f) >> CCF_ARG_SHIFT)
55 |
56 | LJ_FUNC int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags);
57 | LJ_FUNC void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s,
58 | uint8_t *dp, uint8_t *sp, CTInfo flags);
59 | LJ_FUNC int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid,
60 | TValue *o, uint8_t *sp);
61 | LJ_FUNC int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp);
62 | LJ_FUNC void lj_cconv_ct_tv(CTState *cts, CType *d,
63 | uint8_t *dp, TValue *o, CTInfo flags);
64 | LJ_FUNC void lj_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o);
65 | LJ_FUNC int lj_cconv_multi_init(CTState *cts, CType *d, TValue *o);
66 | LJ_FUNC void lj_cconv_ct_init(CTState *cts, CType *d, CTSize sz,
67 | uint8_t *dp, TValue *o, MSize len);
68 |
69 | #endif
70 |
71 | #endif
72 |
--------------------------------------------------------------------------------
/src/lj_cdata.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** C data management.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_CDATA_H
7 | #define _LJ_CDATA_H
8 |
9 | #include "lj_obj.h"
10 | #include "lj_gc.h"
11 | #include "lj_ctype.h"
12 |
13 | #if LJ_HASFFI
14 |
15 | /* Get C data pointer. */
16 | static LJ_AINLINE void *cdata_getptr(void *p, CTSize sz)
17 | {
18 | if (LJ_64 && sz == 4) { /* Support 32 bit pointers on 64 bit targets. */
19 | return ((void *)(uintptr_t)*(uint32_t *)p);
20 | } else {
21 | lj_assertX(sz == CTSIZE_PTR, "bad pointer size %d", sz);
22 | return *(void **)p;
23 | }
24 | }
25 |
26 | /* Set C data pointer. */
27 | static LJ_AINLINE void cdata_setptr(void *p, CTSize sz, const void *v)
28 | {
29 | if (LJ_64 && sz == 4) { /* Support 32 bit pointers on 64 bit targets. */
30 | *(uint32_t *)p = (uint32_t)(uintptr_t)v;
31 | } else {
32 | lj_assertX(sz == CTSIZE_PTR, "bad pointer size %d", sz);
33 | *(void **)p = (void *)v;
34 | }
35 | }
36 |
37 | /* Allocate fixed-size C data object. */
38 | static LJ_AINLINE GCcdata *lj_cdata_new(CTState *cts, CTypeID id, CTSize sz)
39 | {
40 | GCcdata *cd;
41 | #ifdef LUA_USE_ASSERT
42 | CType *ct = ctype_raw(cts, id);
43 | lj_assertCTS((ctype_hassize(ct->info) ? ct->size : CTSIZE_PTR) == sz,
44 | "inconsistent size of fixed-size cdata alloc");
45 | #endif
46 | cd = (GCcdata *)lj_mem_newgco(cts->L, sizeof(GCcdata) + sz);
47 | cd->gct = ~LJ_TCDATA;
48 | cd->ctypeid = ctype_check(cts, id);
49 | return cd;
50 | }
51 |
52 | /* Variant which works without a valid CTState. */
53 | static LJ_AINLINE GCcdata *lj_cdata_new_(lua_State *L, CTypeID id, CTSize sz)
54 | {
55 | GCcdata *cd = (GCcdata *)lj_mem_newgco(L, sizeof(GCcdata) + sz);
56 | cd->gct = ~LJ_TCDATA;
57 | cd->ctypeid = id;
58 | return cd;
59 | }
60 |
61 | LJ_FUNC GCcdata *lj_cdata_newref(CTState *cts, const void *pp, CTypeID id);
62 | LJ_FUNC GCcdata *lj_cdata_newv(lua_State *L, CTypeID id, CTSize sz,
63 | CTSize align);
64 | LJ_FUNC GCcdata *lj_cdata_newx(CTState *cts, CTypeID id, CTSize sz,
65 | CTInfo info);
66 |
67 | LJ_FUNC void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd);
68 | LJ_FUNC void lj_cdata_setfin(lua_State *L, GCcdata *cd, GCobj *obj,
69 | uint32_t it);
70 |
71 | LJ_FUNC CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key,
72 | uint8_t **pp, CTInfo *qual);
73 | LJ_FUNC int lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp);
74 | LJ_FUNC void lj_cdata_set(CTState *cts, CType *d, uint8_t *dp, TValue *o,
75 | CTInfo qual);
76 |
77 | #endif
78 |
79 | #endif
80 |
--------------------------------------------------------------------------------
/src/lj_char.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Character types.
3 | ** Donated to the public domain.
4 | **
5 | ** This is intended to replace the problematic libc single-byte NLS functions.
6 | ** These just don't make sense anymore with UTF-8 locales becoming the norm
7 | ** on POSIX systems. It never worked too well on Windows systems since hardly
8 | ** anyone bothered to call setlocale().
9 | **
10 | ** This table is hardcoded for ASCII. Identifiers include the characters
11 | ** 128-255, too. This allows for the use of all non-ASCII chars as identifiers
12 | ** in the lexer. This is a broad definition, but works well in practice
13 | ** for both UTF-8 locales and most single-byte locales (such as ISO-8859-*).
14 | **
15 | ** If you really need proper character types for UTF-8 strings, please use
16 | ** an add-on library such as slnunicode: http://luaforge.net/projects/sln/
17 | */
18 |
19 | #define lj_char_c
20 | #define LUA_CORE
21 |
22 | #include "lj_char.h"
23 |
24 | LJ_DATADEF const uint8_t lj_char_bits[257] = {
25 | 0,
26 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1,
27 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
28 | 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
29 | 152,152,152,152,152,152,152,152,152,152, 4, 4, 4, 4, 4, 4,
30 | 4,176,176,176,176,176,176,160,160,160,160,160,160,160,160,160,
31 | 160,160,160,160,160,160,160,160,160,160,160, 4, 4, 4, 4,132,
32 | 4,208,208,208,208,208,208,192,192,192,192,192,192,192,192,192,
33 | 192,192,192,192,192,192,192,192,192,192,192, 4, 4, 4, 4, 1,
34 | 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
35 | 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
36 | 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
37 | 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
38 | 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
39 | 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
40 | 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
41 | 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
42 | };
43 |
44 |
--------------------------------------------------------------------------------
/src/lj_char.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Character types.
3 | ** Donated to the public domain.
4 | */
5 |
6 | #ifndef _LJ_CHAR_H
7 | #define _LJ_CHAR_H
8 |
9 | #include "lj_def.h"
10 |
11 | #define LJ_CHAR_CNTRL 0x01
12 | #define LJ_CHAR_SPACE 0x02
13 | #define LJ_CHAR_PUNCT 0x04
14 | #define LJ_CHAR_DIGIT 0x08
15 | #define LJ_CHAR_XDIGIT 0x10
16 | #define LJ_CHAR_UPPER 0x20
17 | #define LJ_CHAR_LOWER 0x40
18 | #define LJ_CHAR_IDENT 0x80
19 | #define LJ_CHAR_ALPHA (LJ_CHAR_LOWER|LJ_CHAR_UPPER)
20 | #define LJ_CHAR_ALNUM (LJ_CHAR_ALPHA|LJ_CHAR_DIGIT)
21 | #define LJ_CHAR_GRAPH (LJ_CHAR_ALNUM|LJ_CHAR_PUNCT)
22 |
23 | /* Only pass -1 or 0..255 to these macros. Never pass a signed char! */
24 | #define lj_char_isa(c, t) ((lj_char_bits+1)[(c)] & t)
25 | #define lj_char_iscntrl(c) lj_char_isa((c), LJ_CHAR_CNTRL)
26 | #define lj_char_isspace(c) lj_char_isa((c), LJ_CHAR_SPACE)
27 | #define lj_char_ispunct(c) lj_char_isa((c), LJ_CHAR_PUNCT)
28 | #define lj_char_isdigit(c) lj_char_isa((c), LJ_CHAR_DIGIT)
29 | #define lj_char_isxdigit(c) lj_char_isa((c), LJ_CHAR_XDIGIT)
30 | #define lj_char_isupper(c) lj_char_isa((c), LJ_CHAR_UPPER)
31 | #define lj_char_islower(c) lj_char_isa((c), LJ_CHAR_LOWER)
32 | #define lj_char_isident(c) lj_char_isa((c), LJ_CHAR_IDENT)
33 | #define lj_char_isalpha(c) lj_char_isa((c), LJ_CHAR_ALPHA)
34 | #define lj_char_isalnum(c) lj_char_isa((c), LJ_CHAR_ALNUM)
35 | #define lj_char_isgraph(c) lj_char_isa((c), LJ_CHAR_GRAPH)
36 |
37 | #define lj_char_toupper(c) ((c) - (lj_char_islower(c) >> 1))
38 | #define lj_char_tolower(c) ((c) + lj_char_isupper(c))
39 |
40 | LJ_DATA const uint8_t lj_char_bits[257];
41 |
42 | #endif
43 |
--------------------------------------------------------------------------------
/src/lj_clib.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** FFI C library loader.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_CLIB_H
7 | #define _LJ_CLIB_H
8 |
9 | #include "lj_obj.h"
10 |
11 | #if LJ_HASFFI
12 |
13 | /* Namespace for C library indexing. */
14 | #define CLNS_INDEX ((1u<env. */
20 | } CLibrary;
21 |
22 | LJ_FUNC TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name);
23 | LJ_FUNC void lj_clib_load(lua_State *L, GCtab *mt, GCstr *name, int global);
24 | LJ_FUNC void lj_clib_unload(CLibrary *cl);
25 | LJ_FUNC void lj_clib_default(lua_State *L, GCtab *mt);
26 |
27 | #endif
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/src/lj_cparse.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** C declaration parser.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_CPARSE_H
7 | #define _LJ_CPARSE_H
8 |
9 | #include "lj_obj.h"
10 | #include "lj_ctype.h"
11 |
12 | #if LJ_HASFFI
13 |
14 | /* C parser limits. */
15 | #define CPARSE_MAX_BUF 32768 /* Max. token buffer size. */
16 | #define CPARSE_MAX_DECLSTACK 100 /* Max. declaration stack depth. */
17 | #define CPARSE_MAX_DECLDEPTH 20 /* Max. recursive declaration depth. */
18 | #define CPARSE_MAX_PACKSTACK 7 /* Max. pack pragma stack depth. */
19 |
20 | /* Flags for C parser mode. */
21 | #define CPARSE_MODE_MULTI 1 /* Process multiple declarations. */
22 | #define CPARSE_MODE_ABSTRACT 2 /* Accept abstract declarators. */
23 | #define CPARSE_MODE_DIRECT 4 /* Accept direct declarators. */
24 | #define CPARSE_MODE_FIELD 8 /* Accept field width in bits, too. */
25 | #define CPARSE_MODE_NOIMPLICIT 16 /* Reject implicit declarations. */
26 | #define CPARSE_MODE_SKIP 32 /* Skip definitions, ignore errors. */
27 |
28 | typedef int CPChar; /* C parser character. Unsigned ext. from char. */
29 | typedef int CPToken; /* C parser token. */
30 |
31 | /* C parser internal value representation. */
32 | typedef struct CPValue {
33 | union {
34 | int32_t i32; /* Value for CTID_INT32. */
35 | uint32_t u32; /* Value for CTID_UINT32. */
36 | };
37 | CTypeID id; /* C Type ID of the value. */
38 | } CPValue;
39 |
40 | /* C parser state. */
41 | typedef struct CPState {
42 | CPChar c; /* Current character. */
43 | CPToken tok; /* Current token. */
44 | CPValue val; /* Token value. */
45 | GCstr *str; /* Interned string of identifier/keyword. */
46 | CType *ct; /* C type table entry. */
47 | const char *p; /* Current position in input buffer. */
48 | SBuf sb; /* String buffer for tokens. */
49 | lua_State *L; /* Lua state. */
50 | CTState *cts; /* C type state. */
51 | TValue *param; /* C type parameters. */
52 | const char *srcname; /* Current source name. */
53 | BCLine linenumber; /* Input line counter. */
54 | int depth; /* Recursive declaration depth. */
55 | uint32_t tmask; /* Type mask for next identifier. */
56 | uint32_t mode; /* C parser mode. */
57 | uint8_t packstack[CPARSE_MAX_PACKSTACK]; /* Stack for pack pragmas. */
58 | uint8_t curpack; /* Current position in pack pragma stack. */
59 | } CPState;
60 |
61 | LJ_FUNC int lj_cparse(CPState *cp);
62 |
63 | LJ_FUNC int lj_cparse_case(GCstr *str, const char *match);
64 |
65 | #endif
66 |
67 | #endif
68 |
--------------------------------------------------------------------------------
/src/lj_crecord.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Trace recorder for C data operations.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_CRECORD_H
7 | #define _LJ_CRECORD_H
8 |
9 | #include "lj_obj.h"
10 | #include "lj_jit.h"
11 | #include "lj_ffrecord.h"
12 |
13 | #if LJ_HASJIT && LJ_HASFFI
14 | LJ_FUNC void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd);
15 | LJ_FUNC void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd);
16 | LJ_FUNC void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd);
17 | LJ_FUNC void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd);
18 | LJ_FUNC void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd);
19 | LJ_FUNC void LJ_FASTCALL recff_ffi_errno(jit_State *J, RecordFFData *rd);
20 | LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd);
21 | LJ_FUNC void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd);
22 | LJ_FUNC void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd);
23 | LJ_FUNC void LJ_FASTCALL recff_ffi_typeof(jit_State *J, RecordFFData *rd);
24 | LJ_FUNC void LJ_FASTCALL recff_ffi_istype(jit_State *J, RecordFFData *rd);
25 | LJ_FUNC void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd);
26 | LJ_FUNC void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd);
27 | LJ_FUNC void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd);
28 |
29 | LJ_FUNC void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd);
30 | LJ_FUNC int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd);
31 | LJ_FUNC int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd);
32 | LJ_FUNC int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd);
33 | LJ_FUNC TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr);
34 |
35 | LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
36 | LJ_FUNC TRef lj_crecord_loadiu64(jit_State *J, TRef tr, cTValue *o);
37 | #if LJ_HASBUFFER
38 | LJ_FUNC TRef lj_crecord_topcvoid(jit_State *J, TRef tr, cTValue *o);
39 | LJ_FUNC TRef lj_crecord_topuint8(jit_State *J, TRef tr);
40 | #endif
41 | #endif
42 |
43 | #endif
44 |
--------------------------------------------------------------------------------
/src/lj_debug.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Debugging and introspection.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_DEBUG_H
7 | #define _LJ_DEBUG_H
8 |
9 | #include "lj_obj.h"
10 |
11 | typedef struct lj_Debug {
12 | /* Common fields. Must be in the same order as in lua.h. */
13 | int event;
14 | const char *name;
15 | const char *namewhat;
16 | const char *what;
17 | const char *source;
18 | int currentline;
19 | int nups;
20 | int linedefined;
21 | int lastlinedefined;
22 | char short_src[LUA_IDSIZE];
23 | int i_ci;
24 | /* Extended fields. Only valid if lj_debug_getinfo() is called with ext = 1.*/
25 | int nparams;
26 | int isvararg;
27 | } lj_Debug;
28 |
29 | LJ_FUNC BCPos lj_debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe);
30 | LJ_FUNC cTValue *lj_debug_frame(lua_State *L, int level, int *size);
31 | LJ_FUNC BCLine LJ_FASTCALL lj_debug_line(GCproto *pt, BCPos pc);
32 | LJ_FUNC const char *lj_debug_uvname(GCproto *pt, uint32_t idx);
33 | LJ_FUNC const char *lj_debug_uvnamev(cTValue *o, uint32_t idx, TValue **tvp,
34 | GCobj **op);
35 | LJ_FUNC const char *lj_debug_slotname(GCproto *pt, const BCIns *pc,
36 | BCReg slot, const char **name);
37 | LJ_FUNC const char *lj_debug_funcname(lua_State *L, cTValue *frame,
38 | const char **name);
39 | LJ_FUNC void lj_debug_shortname(char *out, GCstr *str, BCLine line);
40 | LJ_FUNC void lj_debug_addloc(lua_State *L, const char *msg,
41 | cTValue *frame, cTValue *nextframe);
42 | LJ_FUNC void lj_debug_pushloc(lua_State *L, GCproto *pt, BCPos pc);
43 | LJ_FUNC int lj_debug_getinfo(lua_State *L, const char *what, lj_Debug *ar,
44 | int ext);
45 | #if LJ_HASPROFILE
46 | LJ_FUNC void lj_debug_dumpstack(lua_State *L, SBuf *sb, const char *fmt,
47 | int depth);
48 | #endif
49 |
50 | /* Fixed internal variable names. */
51 | #define VARNAMEDEF(_) \
52 | _(FOR_IDX, "(for index)") \
53 | _(FOR_STOP, "(for limit)") \
54 | _(FOR_STEP, "(for step)") \
55 | _(FOR_GEN, "(for generator)") \
56 | _(FOR_STATE, "(for state)") \
57 | _(FOR_CTL, "(for control)")
58 |
59 | enum {
60 | VARNAME_END,
61 | #define VARNAMEENUM(name, str) VARNAME_##name,
62 | VARNAMEDEF(VARNAMEENUM)
63 | #undef VARNAMEENUM
64 | VARNAME__MAX
65 | };
66 |
67 | #ifdef LUA_USE_TRACE_LOGS
68 | LJ_FUNC void LJ_FASTCALL lj_log_trace_direct_exit(lua_State *L,
69 | int vmstate, const BCIns *pc);
70 | LJ_FUNC void LJ_FASTCALL lj_log_trace_normal_exit(lua_State *L,
71 | int vmstate, const BCIns *pc);
72 | LJ_FUNC void LJ_FASTCALL lj_log_trace_entry(lua_State *L,
73 | unsigned traceno, const BCIns *pc);
74 | LJ_FUNC void LJ_FASTCALL lj_log_trace_start_record(lua_State *L, unsigned traceno,
75 | const BCIns *pc, GCfunc *fn);
76 | #endif
77 |
78 | #endif
79 |
--------------------------------------------------------------------------------
/src/lj_dispatch.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Instruction dispatch handling.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_DISPATCH_H
7 | #define _LJ_DISPATCH_H
8 |
9 | #include "lj_obj.h"
10 | #include "lj_bc.h"
11 | #if LJ_HASJIT
12 | #include "lj_jit.h"
13 | #endif
14 |
15 | #if LJ_TARGET_MIPS
16 | /* Need our own global offset table for the dreaded MIPS calling conventions. */
17 |
18 | #ifndef _LJ_VM_H
19 | LJ_ASMF int32_t LJ_FASTCALL lj_vm_modi(int32_t a, int32_t b);
20 | #endif
21 |
22 | #if LJ_SOFTFP
23 | #ifndef _LJ_IRCALL_H
24 | extern double __adddf3(double a, double b);
25 | extern double __subdf3(double a, double b);
26 | extern double __muldf3(double a, double b);
27 | extern double __divdf3(double a, double b);
28 | #endif
29 | #define SFGOTDEF(_) _(sqrt) _(__adddf3) _(__subdf3) _(__muldf3) _(__divdf3)
30 | #else
31 | #define SFGOTDEF(_)
32 | #endif
33 | #if LJ_HASJIT
34 | #define JITGOTDEF(_) _(lj_err_trace) _(lj_trace_exit) _(lj_trace_hot)
35 | #else
36 | #define JITGOTDEF(_)
37 | #endif
38 | #if LJ_HASFFI
39 | #define FFIGOTDEF(_) \
40 | _(lj_meta_equal_cd) _(lj_ccallback_enter) _(lj_ccallback_leave)
41 | #else
42 | #define FFIGOTDEF(_)
43 | #endif
44 | #define GOTDEF(_) \
45 | _(floor) _(ceil) _(trunc) _(log) _(log10) _(exp) _(sin) _(cos) _(tan) \
46 | _(asin) _(acos) _(atan) _(sinh) _(cosh) _(tanh) _(frexp) _(modf) _(atan2) \
47 | _(pow) _(fmod) _(ldexp) _(lj_vm_modi) \
48 | _(lj_dispatch_call) _(lj_dispatch_ins) _(lj_dispatch_stitch) \
49 | _(lj_dispatch_profile) _(lj_err_throw) \
50 | _(lj_ffh_coroutine_wrap_err) _(lj_func_closeuv) _(lj_func_newL_gc) \
51 | _(lj_gc_barrieruv) _(lj_gc_step) _(lj_gc_step_fixtop) _(lj_meta_arith) \
52 | _(lj_meta_call) _(lj_meta_cat) _(lj_meta_comp) _(lj_meta_equal) \
53 | _(lj_meta_for) _(lj_meta_istype) _(lj_meta_len) _(lj_meta_tget) \
54 | _(lj_meta_tset) _(lj_state_growstack) _(lj_strfmt_number) \
55 | _(lj_str_new) _(lj_tab_dup) _(lj_tab_get) _(lj_tab_getinth) _(lj_tab_len) \
56 | _(lj_tab_new) _(lj_tab_newkey) _(lj_tab_next) _(lj_tab_reasize) \
57 | _(lj_tab_setinth) _(lj_buf_putstr_reverse) _(lj_buf_putstr_lower) \
58 | _(lj_buf_putstr_upper) _(lj_buf_tostr) \
59 | JITGOTDEF(_) FFIGOTDEF(_) SFGOTDEF(_)
60 |
61 | enum {
62 | #define GOTENUM(name) LJ_GOT_##name,
63 | GOTDEF(GOTENUM)
64 | #undef GOTENUM
65 | LJ_GOT__MAX
66 | };
67 | #endif
68 |
69 | /* Type of hot counter. Must match the code in the assembler VM. */
70 | /* 16 bits are sufficient. Only 0.0015% overhead with maximum slot penalty. */
71 | typedef uint16_t HotCount;
72 |
73 | /* Number of hot counter hash table entries (must be a power of two). */
74 | #define HOTCOUNT_SIZE 64
75 | #define HOTCOUNT_PCMASK ((HOTCOUNT_SIZE-1)*sizeof(HotCount))
76 |
77 | /* Hotcount decrements. */
78 | #define HOTCOUNT_LOOP 2
79 | #define HOTCOUNT_CALL 1
80 |
81 | /* This solves a circular dependency problem -- bump as needed. Sigh. */
82 | #define GG_NUM_ASMFF 57
83 |
84 | #define GG_LEN_DDISP (BC__MAX + GG_NUM_ASMFF)
85 | #define GG_LEN_SDISP BC_FUNCF
86 | #define GG_LEN_DISP (GG_LEN_DDISP + GG_LEN_SDISP)
87 |
88 | /* Global state, main thread and extra fields are allocated together. */
89 | typedef struct GG_State {
90 | lua_State L; /* Main thread. */
91 | global_State g; /* Global state. */
92 | #if LJ_TARGET_ARM && !LJ_TARGET_NX
93 | /* Make g reachable via K12 encoded DISPATCH-relative addressing. */
94 | uint8_t align1[(16-sizeof(global_State))&15];
95 | #endif
96 | #if LJ_TARGET_MIPS
97 | ASMFunction got[LJ_GOT__MAX]; /* Global offset table. */
98 | #endif
99 | #if LJ_HASJIT
100 | jit_State J; /* JIT state. */
101 | HotCount hotcount[HOTCOUNT_SIZE]; /* Hot counters. */
102 | #if LJ_TARGET_ARM && !LJ_TARGET_NX
103 | /* Ditto for J. */
104 | uint8_t align2[(16-sizeof(jit_State)-sizeof(HotCount)*HOTCOUNT_SIZE)&15];
105 | #endif
106 | #endif
107 | ASMFunction dispatch[GG_LEN_DISP]; /* Instruction dispatch tables. */
108 | BCIns bcff[GG_NUM_ASMFF]; /* Bytecode for ASM fast functions. */
109 | } GG_State;
110 |
111 | #define GG_OFS(field) ((int)offsetof(GG_State, field))
112 | #define G2GG(gl) ((GG_State *)((char *)(gl) - GG_OFS(g)))
113 | #define J2GG(j) ((GG_State *)((char *)(j) - GG_OFS(J)))
114 | #define L2GG(L) (G2GG(G(L)))
115 | #define J2G(J) (&J2GG(J)->g)
116 | #define G2J(gl) (&G2GG(gl)->J)
117 | #define L2J(L) (&L2GG(L)->J)
118 | #define GG_G2J (GG_OFS(J) - GG_OFS(g))
119 | #define GG_G2DISP (GG_OFS(dispatch) - GG_OFS(g))
120 | #define GG_DISP2G (GG_OFS(g) - GG_OFS(dispatch))
121 | #define GG_DISP2J (GG_OFS(J) - GG_OFS(dispatch))
122 | #define GG_DISP2HOT (GG_OFS(hotcount) - GG_OFS(dispatch))
123 | #define GG_DISP2STATIC (GG_LEN_DDISP*(int)sizeof(ASMFunction))
124 |
125 | #define hotcount_get(gg, pc) \
126 | (gg)->hotcount[(u32ptr(pc)>>2) & (HOTCOUNT_SIZE-1)]
127 | #define hotcount_set(gg, pc, val) \
128 | (hotcount_get((gg), (pc)) = (HotCount)(val))
129 |
130 | /* Dispatch table management. */
131 | LJ_FUNC void lj_dispatch_init(GG_State *GG);
132 | #if LJ_HASJIT
133 | LJ_FUNC void lj_dispatch_init_hotcount(global_State *g);
134 | #endif
135 | LJ_FUNC void lj_dispatch_update(global_State *g);
136 |
137 | /* Instruction dispatch callback for hooks or when recording. */
138 | LJ_FUNCA void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc);
139 | LJ_FUNCA ASMFunction LJ_FASTCALL lj_dispatch_call(lua_State *L, const BCIns*pc);
140 | #if LJ_HASJIT
141 | LJ_FUNCA void LJ_FASTCALL lj_dispatch_stitch(jit_State *J, const BCIns *pc);
142 | #endif
143 | #if LJ_HASPROFILE
144 | LJ_FUNCA void LJ_FASTCALL lj_dispatch_profile(lua_State *L, const BCIns *pc);
145 | #endif
146 |
147 | #if LJ_HASFFI && !defined(_BUILDVM_H)
148 | /* Save/restore errno and GetLastError() around hooks, exits and recording. */
149 | #include
150 | #if LJ_TARGET_WINDOWS
151 | #define WIN32_LEAN_AND_MEAN
152 | #include
153 | #define ERRNO_SAVE int olderr = errno; DWORD oldwerr = GetLastError();
154 | #define ERRNO_RESTORE errno = olderr; SetLastError(oldwerr);
155 | #else
156 | #define ERRNO_SAVE int olderr = errno;
157 | #define ERRNO_RESTORE errno = olderr;
158 | #endif
159 | #else
160 | #define ERRNO_SAVE
161 | #define ERRNO_RESTORE
162 | #endif
163 |
164 | #endif
165 |
--------------------------------------------------------------------------------
/src/lj_err.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Error handling.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_ERR_H
7 | #define _LJ_ERR_H
8 |
9 | #include
10 |
11 | #include "lj_obj.h"
12 |
13 | typedef enum {
14 | #define ERRDEF(name, msg) \
15 | LJ_ERR_##name, LJ_ERR_##name##_ = LJ_ERR_##name + sizeof(msg)-1,
16 | #include "lj_errmsg.h"
17 | LJ_ERR__MAX
18 | } ErrMsg;
19 |
20 | LJ_DATA const char *lj_err_allmsg;
21 | #define err2msg(em) (lj_err_allmsg+(int)(em))
22 |
23 | LJ_FUNC GCstr *lj_err_str(lua_State *L, ErrMsg em);
24 | LJ_FUNCA_NORET void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode);
25 | LJ_FUNC_NORET void lj_err_mem(lua_State *L);
26 | LJ_FUNC_NORET void LJ_FASTCALL lj_err_stkov(lua_State *L);
27 | LJ_FUNC_NORET void LJ_FASTCALL lj_err_run(lua_State *L);
28 | #if LJ_HASJIT
29 | LJ_FUNCA_NORET void LJ_FASTCALL lj_err_trace(lua_State *L, int errcode);
30 | #endif
31 | LJ_FUNC_NORET void lj_err_msg(lua_State *L, ErrMsg em);
32 | LJ_FUNC_NORET void lj_err_lex(lua_State *L, GCstr *src, const char *tok,
33 | BCLine line, ErrMsg em, va_list argp);
34 | LJ_FUNC_NORET void lj_err_optype(lua_State *L, cTValue *o, ErrMsg opm);
35 | LJ_FUNC_NORET void lj_err_comp(lua_State *L, cTValue *o1, cTValue *o2);
36 | LJ_FUNC_NORET void lj_err_optype_call(lua_State *L, TValue *o);
37 | LJ_FUNC_NORET void lj_err_callermsg(lua_State *L, const char *msg);
38 | LJ_FUNC_NORET void lj_err_callerv(lua_State *L, ErrMsg em, ...);
39 | LJ_FUNC_NORET void lj_err_caller(lua_State *L, ErrMsg em);
40 | LJ_FUNC_NORET void lj_err_arg(lua_State *L, int narg, ErrMsg em);
41 | LJ_FUNC_NORET void lj_err_argv(lua_State *L, int narg, ErrMsg em, ...);
42 | LJ_FUNC_NORET void lj_err_argtype(lua_State *L, int narg, const char *xname);
43 | LJ_FUNC_NORET void lj_err_argt(lua_State *L, int narg, int tt);
44 |
45 | #if LJ_UNWIND_JIT && !LJ_ABI_WIN
46 | LJ_FUNC uint8_t *lj_err_register_mcode(void *base, size_t sz, uint8_t *info);
47 | LJ_FUNC void lj_err_deregister_mcode(void *base, size_t sz, uint8_t *info);
48 | #else
49 | #define lj_err_register_mcode(base, sz, info) (info)
50 | #define lj_err_deregister_mcode(base, sz, info) UNUSED(base)
51 | #endif
52 |
53 | #if LJ_UNWIND_EXT && !LJ_ABI_WIN && defined(LUA_USE_ASSERT)
54 | LJ_FUNC void lj_err_verify(void);
55 | #else
56 | #define lj_err_verify() ((void)0)
57 | #endif
58 |
59 | #endif
60 |
--------------------------------------------------------------------------------
/src/lj_ff.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Fast function IDs.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_FF_H
7 | #define _LJ_FF_H
8 |
9 | /* Fast function ID. */
10 | typedef enum {
11 | FF_LUA_ = FF_LUA, /* Lua function (must be 0). */
12 | FF_C_ = FF_C, /* Regular C function (must be 1). */
13 | #define FFDEF(name) FF_##name,
14 | #include "lj_ffdef.h"
15 | FF__MAX
16 | } FastFunc;
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/src/lj_ffrecord.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Fast function call recorder.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_FFRECORD_H
7 | #define _LJ_FFRECORD_H
8 |
9 | #include "lj_obj.h"
10 | #include "lj_jit.h"
11 |
12 | #if LJ_HASJIT
13 | /* Data used by handlers to record a fast function. */
14 | typedef struct RecordFFData {
15 | TValue *argv; /* Runtime argument values. */
16 | ptrdiff_t nres; /* Number of returned results (defaults to 1). */
17 | uint32_t data; /* Per-ffid auxiliary data (opcode, literal etc.). */
18 | } RecordFFData;
19 |
20 | LJ_FUNC int32_t lj_ffrecord_select_mode(jit_State *J, TRef tr, TValue *tv);
21 | LJ_FUNC void lj_ffrecord_func(jit_State *J);
22 | #endif
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/src/lj_func.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Function handling (prototypes, functions and upvalues).
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_FUNC_H
7 | #define _LJ_FUNC_H
8 |
9 | #include "lj_obj.h"
10 |
11 | /* Prototypes. */
12 | LJ_FUNC void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt);
13 |
14 | /* Upvalues. */
15 | LJ_FUNCA void LJ_FASTCALL lj_func_closeuv(lua_State *L, TValue *level);
16 | LJ_FUNC void LJ_FASTCALL lj_func_freeuv(global_State *g, GCupval *uv);
17 |
18 | /* Functions (closures). */
19 | LJ_FUNC GCfunc *lj_func_newC(lua_State *L, MSize nelems, GCtab *env);
20 | LJ_FUNC GCfunc *lj_func_newL_empty(lua_State *L, GCproto *pt, GCtab *env);
21 | LJ_FUNCA GCfunc *lj_func_newL_gc(lua_State *L, GCproto *pt, GCfuncL *parent);
22 | LJ_FUNC void LJ_FASTCALL lj_func_free(global_State *g, GCfunc *c);
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/src/lj_gc.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Garbage collector.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_GC_H
7 | #define _LJ_GC_H
8 |
9 | #include "lj_obj.h"
10 |
11 | /* Garbage collector states. Order matters. */
12 | enum {
13 | GCSpause, GCSpropagate, GCSatomic, GCSsweepstring, GCSsweep, GCSfinalize
14 | };
15 |
16 | /* Bitmasks for marked field of GCobj. */
17 | #define LJ_GC_WHITE0 0x01
18 | #define LJ_GC_WHITE1 0x02
19 | #define LJ_GC_BLACK 0x04
20 | #define LJ_GC_FINALIZED 0x08
21 | #define LJ_GC_WEAKKEY 0x08
22 | #define LJ_GC_WEAKVAL 0x10
23 | #define LJ_GC_CDATA_FIN 0x10
24 | #define LJ_GC_FIXED 0x20
25 | #define LJ_GC_SFIXED 0x40
26 |
27 | #define LJ_GC_WHITES (LJ_GC_WHITE0 | LJ_GC_WHITE1)
28 | #define LJ_GC_COLORS (LJ_GC_WHITES | LJ_GC_BLACK)
29 | #define LJ_GC_WEAK (LJ_GC_WEAKKEY | LJ_GC_WEAKVAL)
30 |
31 | /* Macros to test and set GCobj colors. */
32 | #define iswhite(x) ((x)->gch.marked & LJ_GC_WHITES)
33 | #define isblack(x) ((x)->gch.marked & LJ_GC_BLACK)
34 | #define isgray(x) (!((x)->gch.marked & (LJ_GC_BLACK|LJ_GC_WHITES)))
35 | #define tviswhite(x) (tvisgcv(x) && iswhite(gcV(x)))
36 | #define otherwhite(g) (g->gc.currentwhite ^ LJ_GC_WHITES)
37 | #define isdead(g, v) ((v)->gch.marked & otherwhite(g) & LJ_GC_WHITES)
38 |
39 | #define curwhite(g) ((g)->gc.currentwhite & LJ_GC_WHITES)
40 | #define newwhite(g, x) (obj2gco(x)->gch.marked = (uint8_t)curwhite(g))
41 | #define makewhite(g, x) \
42 | ((x)->gch.marked = ((x)->gch.marked & (uint8_t)~LJ_GC_COLORS) | curwhite(g))
43 | #define flipwhite(x) ((x)->gch.marked ^= LJ_GC_WHITES)
44 | #define black2gray(x) ((x)->gch.marked &= (uint8_t)~LJ_GC_BLACK)
45 | #define fixstring(s) ((s)->marked |= LJ_GC_FIXED)
46 | #define markfinalized(x) ((x)->gch.marked |= LJ_GC_FINALIZED)
47 |
48 | /* Collector. */
49 | LJ_FUNC size_t lj_gc_separateudata(global_State *g, int all);
50 | LJ_FUNC void lj_gc_finalize_udata(lua_State *L);
51 | #if LJ_HASFFI
52 | LJ_FUNC void lj_gc_finalize_cdata(lua_State *L);
53 | #else
54 | #define lj_gc_finalize_cdata(L) UNUSED(L)
55 | #endif
56 | LJ_FUNC void lj_gc_freeall(global_State *g);
57 | LJ_FUNCA int LJ_FASTCALL lj_gc_step(lua_State *L);
58 | LJ_FUNCA void LJ_FASTCALL lj_gc_step_fixtop(lua_State *L);
59 | #if LJ_HASJIT
60 | LJ_FUNC int LJ_FASTCALL lj_gc_step_jit(global_State *g, MSize steps);
61 | #endif
62 | LJ_FUNC void lj_gc_fullgc(lua_State *L);
63 |
64 | /* GC check: drive collector forward if the GC threshold has been reached. */
65 | #define lj_gc_check(L) \
66 | { if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) \
67 | lj_gc_step(L); }
68 | #define lj_gc_check_fixtop(L) \
69 | { if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) \
70 | lj_gc_step_fixtop(L); }
71 |
72 | /* Write barriers. */
73 | LJ_FUNC void lj_gc_barrierf(global_State *g, GCobj *o, GCobj *v);
74 | LJ_FUNCA void LJ_FASTCALL lj_gc_barrieruv(global_State *g, TValue *tv);
75 | LJ_FUNC void lj_gc_closeuv(global_State *g, GCupval *uv);
76 | #if LJ_HASJIT
77 | LJ_FUNC void lj_gc_barriertrace(global_State *g, uint32_t traceno);
78 | #endif
79 |
80 | /* Move the GC propagation frontier back for tables (make it gray again). */
81 | static LJ_AINLINE void lj_gc_barrierback(global_State *g, GCtab *t)
82 | {
83 | GCobj *o = obj2gco(t);
84 | lj_assertG(isblack(o) && !isdead(g, o),
85 | "bad object states for backward barrier");
86 | lj_assertG(g->gc.state != GCSfinalize && g->gc.state != GCSpause,
87 | "bad GC state");
88 | black2gray(o);
89 | setgcrefr(t->gclist, g->gc.grayagain);
90 | setgcref(g->gc.grayagain, o);
91 | }
92 |
93 | /* Barrier for stores to table objects. TValue and GCobj variant. */
94 | #define lj_gc_anybarriert(L, t) \
95 | { if (LJ_UNLIKELY(isblack(obj2gco(t)))) lj_gc_barrierback(G(L), (t)); }
96 | #define lj_gc_barriert(L, t, tv) \
97 | { if (tviswhite(tv) && isblack(obj2gco(t))) \
98 | lj_gc_barrierback(G(L), (t)); }
99 | #define lj_gc_objbarriert(L, t, o) \
100 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) \
101 | lj_gc_barrierback(G(L), (t)); }
102 |
103 | /* Barrier for stores to any other object. TValue and GCobj variant. */
104 | #define lj_gc_barrier(L, p, tv) \
105 | { if (tviswhite(tv) && isblack(obj2gco(p))) \
106 | lj_gc_barrierf(G(L), obj2gco(p), gcV(tv)); }
107 | #define lj_gc_objbarrier(L, p, o) \
108 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
109 | lj_gc_barrierf(G(L), obj2gco(p), obj2gco(o)); }
110 |
111 | /* Allocator. */
112 | LJ_FUNC void *lj_mem_realloc(lua_State *L, void *p, GCSize osz, GCSize nsz);
113 | LJ_FUNC void * LJ_FASTCALL lj_mem_newgco(lua_State *L, GCSize size);
114 | LJ_FUNC void *lj_mem_grow(lua_State *L, void *p,
115 | MSize *szp, MSize lim, MSize esz);
116 |
117 | #define lj_mem_new(L, s) lj_mem_realloc(L, NULL, 0, (s))
118 |
119 | static LJ_AINLINE void lj_mem_free(global_State *g, void *p, size_t osize)
120 | {
121 | g->gc.total -= (GCSize)osize;
122 | g->allocf(g->allocd, p, osize, 0);
123 | }
124 |
125 | #define lj_mem_newvec(L, n, t) ((t *)lj_mem_new(L, (GCSize)((n)*sizeof(t))))
126 | #define lj_mem_reallocvec(L, p, on, n, t) \
127 | ((p) = (t *)lj_mem_realloc(L, p, (on)*sizeof(t), (GCSize)((n)*sizeof(t))))
128 | #define lj_mem_growvec(L, p, n, m, t) \
129 | ((p) = (t *)lj_mem_grow(L, (p), &(n), (m), (MSize)sizeof(t)))
130 | #define lj_mem_freevec(g, p, n, t) lj_mem_free(g, (p), (n)*sizeof(t))
131 |
132 | #define lj_mem_newobj(L, t) ((t *)lj_mem_newgco(L, sizeof(t)))
133 | #define lj_mem_newt(L, s, t) ((t *)lj_mem_new(L, (s)))
134 | #define lj_mem_freet(g, p) lj_mem_free(g, (p), sizeof(*(p)))
135 |
136 | #endif
137 |
--------------------------------------------------------------------------------
/src/lj_gdbjit.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Client for the GDB JIT API.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_GDBJIT_H
7 | #define _LJ_GDBJIT_H
8 |
9 | #include "lj_obj.h"
10 | #include "lj_jit.h"
11 |
12 | #if LJ_HASJIT && defined(LUAJIT_USE_GDBJIT)
13 |
14 | LJ_FUNC void lj_gdbjit_addtrace(jit_State *J, GCtrace *T);
15 | LJ_FUNC void lj_gdbjit_deltrace(jit_State *J, GCtrace *T);
16 |
17 | #else
18 | #define lj_gdbjit_addtrace(J, T) UNUSED(T)
19 | #define lj_gdbjit_deltrace(J, T) UNUSED(T)
20 | #endif
21 |
22 | #endif
23 |
--------------------------------------------------------------------------------
/src/lj_init.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "lj_arch.h"
3 | #include "lj_jit.h"
4 | #include "lj_vm.h"
5 | #include "lj_str.h"
6 |
7 | #if LJ_TARGET_ARM && LJ_TARGET_LINUX
8 | #include
9 | #endif
10 |
11 | #ifdef _MSC_VER
12 | /*
13 | ** Append a function pointer to the static constructor table executed by
14 | ** the C runtime.
15 | ** Based on https://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc
16 | ** see also https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-initialization.
17 | */
18 | #pragma section(".CRT$XCU",read)
19 | #define LJ_INITIALIZER2_(f,p) \
20 | static void f(void); \
21 | __declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
22 | __pragma(comment(linker,"/include:" p #f "_")) \
23 | static void f(void)
24 | #ifdef _WIN64
25 | #define LJ_INITIALIZER(f) LJ_INITIALIZER2_(f,"")
26 | #else
27 | #define LJ_INITIALIZER(f) LJ_INITIALIZER2_(f,"_")
28 | #endif
29 |
30 | #else
31 | #define LJ_INITIALIZER(f) static void __attribute__((constructor)) f(void)
32 | #endif
33 |
34 |
35 | #ifdef LJ_HAS_OPTIMISED_HASH
36 | static void str_hash_init(uint32_t flags)
37 | {
38 | if (flags & JIT_F_SSE4_2)
39 | str_hash_init_sse42 ();
40 | }
41 |
42 | /* CPU detection for interpreter features such as string hash function
43 | selection. We choose to cherry-pick from lj_cpudetect and not have a single
44 | initializer to make sure that merges with LuaJIT/LuaJIT remain
45 | convenient. */
46 | LJ_INITIALIZER(lj_init_cpuflags)
47 | {
48 | uint32_t flags = 0;
49 | #if LJ_TARGET_X86ORX64
50 |
51 | uint32_t vendor[4];
52 | uint32_t features[4];
53 | if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) {
54 | flags |= ((features[2] >> 0)&1) * JIT_F_SSE3;
55 | flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1;
56 | flags |= ((features[2] >> 20)&1) * JIT_F_SSE4_2;
57 | if (vendor[0] >= 7) {
58 | uint32_t xfeatures[4];
59 | lj_vm_cpuid(7, xfeatures);
60 | flags |= ((xfeatures[1] >> 8)&1) * JIT_F_BMI2;
61 | }
62 | }
63 |
64 | #endif
65 |
66 | /* The reason why we initialized early: select our string hash functions. */
67 | str_hash_init (flags);
68 | }
69 | #endif
70 |
--------------------------------------------------------------------------------
/src/lj_lex.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Lexical analyzer.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_LEX_H
7 | #define _LJ_LEX_H
8 |
9 | #include
10 |
11 | #include "lj_obj.h"
12 | #include "lj_err.h"
13 |
14 | /* Lua lexer tokens. */
15 | #define TKDEF(_, __) \
16 | _(and) _(break) _(do) _(else) _(elseif) _(end) _(false) \
17 | _(for) _(function) _(goto) _(if) _(in) _(local) _(nil) _(not) _(or) \
18 | _(repeat) _(return) _(then) _(true) _(until) _(while) \
19 | __(concat, ..) __(dots, ...) __(eq, ==) __(ge, >=) __(le, <=) __(ne, ~=) \
20 | __(label, ::) __(number, ) __(name, ) __(string, ) \
21 | __(eof, )
22 |
23 | enum {
24 | TK_OFS = 256,
25 | #define TKENUM1(name) TK_##name,
26 | #define TKENUM2(name, sym) TK_##name,
27 | TKDEF(TKENUM1, TKENUM2)
28 | #undef TKENUM1
29 | #undef TKENUM2
30 | TK_RESERVED = TK_while - TK_OFS
31 | };
32 |
33 | typedef int LexChar; /* Lexical character. Unsigned ext. from char. */
34 | typedef int LexToken; /* Lexical token. */
35 |
36 | /* Combined bytecode ins/line. Only used during bytecode generation. */
37 | typedef struct BCInsLine {
38 | BCIns ins; /* Bytecode instruction. */
39 | BCLine line; /* Line number for this bytecode. */
40 | } BCInsLine;
41 |
42 | /* Info for local variables. Only used during bytecode generation. */
43 | typedef struct VarInfo {
44 | GCRef name; /* Local variable name or goto/label name. */
45 | BCPos startpc; /* First point where the local variable is active. */
46 | BCPos endpc; /* First point where the local variable is dead. */
47 | uint8_t slot; /* Variable slot. */
48 | uint8_t info; /* Variable/goto/label info. */
49 | } VarInfo;
50 |
51 | /* Lua lexer state. */
52 | typedef struct LexState {
53 | struct FuncState *fs; /* Current FuncState. Defined in lj_parse.c. */
54 | struct lua_State *L; /* Lua state. */
55 | TValue tokval; /* Current token value. */
56 | TValue lookaheadval; /* Lookahead token value. */
57 | const char *p; /* Current position in input buffer. */
58 | const char *pe; /* End of input buffer. */
59 | LexChar c; /* Current character. */
60 | LexToken tok; /* Current token. */
61 | LexToken lookahead; /* Lookahead token. */
62 | SBuf sb; /* String buffer for tokens. */
63 | lua_Reader rfunc; /* Reader callback. */
64 | void *rdata; /* Reader callback data. */
65 | BCLine linenumber; /* Input line counter. */
66 | BCLine lastline; /* Line of last token. */
67 | GCstr *chunkname; /* Current chunk name (interned string). */
68 | const char *chunkarg; /* Chunk name argument. */
69 | const char *mode; /* Allow loading bytecode (b) and/or source text (t). */
70 | VarInfo *vstack; /* Stack for names and extents of local variables. */
71 | MSize sizevstack; /* Size of variable stack. */
72 | MSize vtop; /* Top of variable stack. */
73 | BCInsLine *bcstack; /* Stack for bytecode instructions/line numbers. */
74 | MSize sizebcstack; /* Size of bytecode stack. */
75 | uint32_t level; /* Syntactical nesting level. */
76 | int endmark; /* Trust bytecode end marker, even if not at EOF. */
77 | int fr2; /* Generate bytecode for LJ_FR2 mode. */
78 | } LexState;
79 |
80 | LJ_FUNC int lj_lex_setup(lua_State *L, LexState *ls);
81 | LJ_FUNC void lj_lex_cleanup(lua_State *L, LexState *ls);
82 | LJ_FUNC void lj_lex_next(LexState *ls);
83 | LJ_FUNC LexToken lj_lex_lookahead(LexState *ls);
84 | LJ_FUNC const char *lj_lex_token2str(LexState *ls, LexToken tok);
85 | LJ_FUNC_NORET void lj_lex_error(LexState *ls, LexToken tok, ErrMsg em, ...);
86 | LJ_FUNC void lj_lex_init(lua_State *L);
87 |
88 | #ifdef LUA_USE_ASSERT
89 | #define lj_assertLS(c, ...) (lj_assertG_(G(ls->L), (c), __VA_ARGS__))
90 | #else
91 | #define lj_assertLS(c, ...) ((void)ls)
92 | #endif
93 |
94 | #endif
95 |
--------------------------------------------------------------------------------
/src/lj_lib.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Library function support.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_LIB_H
7 | #define _LJ_LIB_H
8 |
9 | #include "lj_obj.h"
10 |
11 | /*
12 | ** A fallback handler is called by the assembler VM if the fast path fails:
13 | **
14 | ** - too few arguments: unrecoverable.
15 | ** - wrong argument type: recoverable, if coercion succeeds.
16 | ** - bad argument value: unrecoverable.
17 | ** - stack overflow: recoverable, if stack reallocation succeeds.
18 | ** - extra handling: recoverable.
19 | **
20 | ** The unrecoverable cases throw an error with lj_err_arg(), lj_err_argtype(),
21 | ** lj_err_caller() or lj_err_callermsg().
22 | ** The recoverable cases return 0 or the number of results + 1.
23 | ** The assembler VM retries the fast path only if 0 is returned.
24 | ** This time the fallback must not be called again or it gets stuck in a loop.
25 | */
26 |
27 | /* Return values from fallback handler. */
28 | #define FFH_RETRY 0
29 | #define FFH_UNREACHABLE FFH_RETRY
30 | #define FFH_RES(n) ((n)+1)
31 | #define FFH_TAILCALL (-1)
32 |
33 | LJ_FUNC TValue *lj_lib_checkany(lua_State *L, int narg);
34 | LJ_FUNC GCstr *lj_lib_checkstr(lua_State *L, int narg);
35 | LJ_FUNC GCstr *lj_lib_optstr(lua_State *L, int narg);
36 | #if LJ_DUALNUM
37 | LJ_FUNC void lj_lib_checknumber(lua_State *L, int narg);
38 | #else
39 | #define lj_lib_checknumber(L, narg) lj_lib_checknum((L), (narg))
40 | #endif
41 | LJ_FUNC lua_Number lj_lib_checknum(lua_State *L, int narg);
42 | LJ_FUNC int32_t lj_lib_checkint(lua_State *L, int narg);
43 | LJ_FUNC int32_t lj_lib_optint(lua_State *L, int narg, int32_t def);
44 | LJ_FUNC GCfunc *lj_lib_checkfunc(lua_State *L, int narg);
45 | LJ_FUNC GCproto *lj_lib_checkLproto(lua_State *L, int narg, int nolua);
46 | LJ_FUNC GCtab *lj_lib_checktab(lua_State *L, int narg);
47 | LJ_FUNC GCtab *lj_lib_checktabornil(lua_State *L, int narg);
48 | LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst);
49 | LJ_FUNC GCcdata *lj_lib_checkcdata(lua_State *L, int narg);
50 |
51 | #if LJ_HASBUFFER
52 | LJ_FUNC GCstr *lj_lib_checkstrx(lua_State *L, int narg);
53 | LJ_FUNC int32_t lj_lib_checkintrange(lua_State *L, int narg,
54 | int32_t a, int32_t b);
55 | #endif
56 |
57 | /* Avoid including lj_frame.h. */
58 | #if LJ_GC64
59 | #define lj_lib_upvalue(L, n) \
60 | (&gcval(L->base-2)->fn.c.upvalue[(n)-1])
61 | #elif LJ_FR2
62 | #define lj_lib_upvalue(L, n) \
63 | (&gcref((L->base-2)->gcr)->fn.c.upvalue[(n)-1])
64 | #else
65 | #define lj_lib_upvalue(L, n) \
66 | (&gcref((L->base-1)->fr.func)->fn.c.upvalue[(n)-1])
67 | #endif
68 |
69 | #if LJ_TARGET_WINDOWS
70 | #define lj_lib_checkfpu(L) \
71 | do { setnumV(L->top++, (lua_Number)1437217655); \
72 | if (lua_tointeger(L, -1) != 1437217655) lj_err_caller(L, LJ_ERR_BADFPU); \
73 | L->top--; } while (0)
74 | #else
75 | #define lj_lib_checkfpu(L) UNUSED(L)
76 | #endif
77 |
78 | LJ_FUNC GCfunc *lj_lib_pushcc(lua_State *L, lua_CFunction f, int id, int n);
79 | #define lj_lib_pushcf(L, fn, id) (lj_lib_pushcc(L, (fn), (id), 0))
80 |
81 | /* Library function declarations. Scanned by buildvm. */
82 | #define LJLIB_CF(name) static int lj_cf_##name(lua_State *L)
83 | #define LJLIB_ASM(name) static int lj_ffh_##name(lua_State *L)
84 | #define LJLIB_ASM_(name)
85 | #define LJLIB_LUA(name)
86 | #define LJLIB_SET(name)
87 | #define LJLIB_PUSH(arg)
88 | #define LJLIB_REC(handler)
89 | #define LJLIB_NOREGUV
90 | #define LJLIB_NOREG
91 |
92 | #define LJ_LIB_REG(L, regname, name) \
93 | lj_lib_register(L, regname, lj_lib_init_##name, lj_lib_cf_##name)
94 |
95 | LJ_FUNC void lj_lib_register(lua_State *L, const char *libname,
96 | const uint8_t *init, const lua_CFunction *cf);
97 | LJ_FUNC void lj_lib_prereg(lua_State *L, const char *name, lua_CFunction f,
98 | GCtab *env);
99 | LJ_FUNC int lj_lib_postreg(lua_State *L, lua_CFunction cf, int id,
100 | const char *name);
101 |
102 | /* Library init data tags. */
103 | #define LIBINIT_LENMASK 0x3f
104 | #define LIBINIT_TAGMASK 0xc0
105 | #define LIBINIT_CF 0x00
106 | #define LIBINIT_ASM 0x40
107 | #define LIBINIT_ASM_ 0x80
108 | #define LIBINIT_STRING 0xc0
109 | #define LIBINIT_MAXSTR 0x38
110 | #define LIBINIT_LUA 0xf9
111 | #define LIBINIT_SET 0xfa
112 | #define LIBINIT_NUMBER 0xfb
113 | #define LIBINIT_COPY 0xfc
114 | #define LIBINIT_LASTCL 0xfd
115 | #define LIBINIT_FFID 0xfe
116 | #define LIBINIT_END 0xff
117 |
118 | #endif
119 |
--------------------------------------------------------------------------------
/src/lj_load.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Load and dump code.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #include
7 | #include
8 |
9 | #define lj_load_c
10 | #define LUA_CORE
11 |
12 | #include "lua.h"
13 | #include "lauxlib.h"
14 |
15 | #include "lj_obj.h"
16 | #include "lj_gc.h"
17 | #include "lj_err.h"
18 | #include "lj_buf.h"
19 | #include "lj_func.h"
20 | #include "lj_frame.h"
21 | #include "lj_vm.h"
22 | #include "lj_lex.h"
23 | #include "lj_bcdump.h"
24 | #include "lj_parse.h"
25 |
26 | /* -- Load Lua source code and bytecode ----------------------------------- */
27 |
28 | static TValue *cpparser(lua_State *L, lua_CFunction dummy, void *ud)
29 | {
30 | LexState *ls = (LexState *)ud;
31 | GCproto *pt;
32 | GCfunc *fn;
33 | int bc;
34 | UNUSED(dummy);
35 | cframe_errfunc(L->cframe) = -1; /* Inherit error function. */
36 | bc = lj_lex_setup(L, ls);
37 | if (ls->mode) {
38 | int xmode = 1;
39 | const char *mode = ls->mode;
40 | char c;
41 | while ((c = *mode++)) {
42 | if (c == (bc ? 'b' : 't')) xmode = 0;
43 | if (c == (LJ_FR2 ? 'W' : 'X')) ls->fr2 = !LJ_FR2;
44 | }
45 | if (xmode) {
46 | setstrV(L, L->top++, lj_err_str(L, LJ_ERR_XMODE));
47 | lj_err_throw(L, LUA_ERRSYNTAX);
48 | }
49 | }
50 | pt = bc ? lj_bcread(ls) : lj_parse(ls);
51 | if (ls->fr2 == LJ_FR2) {
52 | fn = lj_func_newL_empty(L, pt, tabref(L->env));
53 | /* Don't combine above/below into one statement. */
54 | setfuncV(L, L->top++, fn);
55 | } else {
56 | /* Non-native generation returns a dumpable, but non-runnable prototype. */
57 | setprotoV(L, L->top++, pt);
58 | }
59 | return NULL;
60 | }
61 |
62 | LUA_API int lua_loadx(lua_State *L, lua_Reader reader, void *data,
63 | const char *chunkname, const char *mode)
64 | {
65 | LexState ls;
66 | int status;
67 | ls.rfunc = reader;
68 | ls.rdata = data;
69 | ls.chunkarg = chunkname ? chunkname : "?";
70 | ls.mode = mode;
71 | lj_buf_init(L, &ls.sb);
72 | status = lj_vm_cpcall(L, NULL, &ls, cpparser);
73 | lj_lex_cleanup(L, &ls);
74 | lj_gc_check(L);
75 | return status;
76 | }
77 |
78 | LUA_API int lua_load(lua_State *L, lua_Reader reader, void *data,
79 | const char *chunkname)
80 | {
81 | return lua_loadx(L, reader, data, chunkname, NULL);
82 | }
83 |
84 | typedef struct FileReaderCtx {
85 | FILE *fp;
86 | char buf[LUAL_BUFFERSIZE];
87 | } FileReaderCtx;
88 |
89 | static const char *reader_file(lua_State *L, void *ud, size_t *size)
90 | {
91 | FileReaderCtx *ctx = (FileReaderCtx *)ud;
92 | UNUSED(L);
93 | if (feof(ctx->fp)) return NULL;
94 | *size = fread(ctx->buf, 1, sizeof(ctx->buf), ctx->fp);
95 | return *size > 0 ? ctx->buf : NULL;
96 | }
97 |
98 | LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename,
99 | const char *mode)
100 | {
101 | FileReaderCtx ctx;
102 | int status;
103 | const char *chunkname;
104 | int err = 0;
105 | if (filename) {
106 | chunkname = lua_pushfstring(L, "@%s", filename);
107 | ctx.fp = fopen(filename, "rb");
108 | if (ctx.fp == NULL) {
109 | L->top--;
110 | lua_pushfstring(L, "cannot open %s: %s", filename, strerror(errno));
111 | return LUA_ERRFILE;
112 | }
113 | } else {
114 | ctx.fp = stdin;
115 | chunkname = "=stdin";
116 | }
117 | status = lua_loadx(L, reader_file, &ctx, chunkname, mode);
118 | if (ferror(ctx.fp)) err = errno;
119 | if (filename) {
120 | fclose(ctx.fp);
121 | L->top--;
122 | copyTV(L, L->top-1, L->top);
123 | }
124 | if (err) {
125 | const char *fname = filename ? filename : "stdin";
126 | L->top--;
127 | lua_pushfstring(L, "cannot read %s: %s", fname, strerror(err));
128 | return LUA_ERRFILE;
129 | }
130 | return status;
131 | }
132 |
133 | LUALIB_API int luaL_loadfile(lua_State *L, const char *filename)
134 | {
135 | return luaL_loadfilex(L, filename, NULL);
136 | }
137 |
138 | typedef struct StringReaderCtx {
139 | const char *str;
140 | size_t size;
141 | } StringReaderCtx;
142 |
143 | static const char *reader_string(lua_State *L, void *ud, size_t *size)
144 | {
145 | StringReaderCtx *ctx = (StringReaderCtx *)ud;
146 | UNUSED(L);
147 | if (ctx->size == 0) return NULL;
148 | *size = ctx->size;
149 | ctx->size = 0;
150 | return ctx->str;
151 | }
152 |
153 | LUALIB_API int luaL_loadbufferx(lua_State *L, const char *buf, size_t size,
154 | const char *name, const char *mode)
155 | {
156 | StringReaderCtx ctx;
157 | ctx.str = buf;
158 | ctx.size = size;
159 | return lua_loadx(L, reader_string, &ctx, name, mode);
160 | }
161 |
162 | LUALIB_API int luaL_loadbuffer(lua_State *L, const char *buf, size_t size,
163 | const char *name)
164 | {
165 | return luaL_loadbufferx(L, buf, size, name, NULL);
166 | }
167 |
168 | LUALIB_API int luaL_loadstring(lua_State *L, const char *s)
169 | {
170 | return luaL_loadbuffer(L, s, strlen(s), s);
171 | }
172 |
173 | /* -- Dump bytecode ------------------------------------------------------- */
174 |
175 | LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data)
176 | {
177 | cTValue *o = L->top-1;
178 | uint32_t flags = LJ_FR2*BCDUMP_F_FR2; /* Default mode for legacy C API. */
179 | lj_checkapi(L->top > L->base, "top slot empty");
180 | if (tvisfunc(o) && isluafunc(funcV(o)))
181 | return lj_bcwrite(L, funcproto(funcV(o)), writer, data, flags);
182 | else
183 | return 1;
184 | }
185 |
186 |
--------------------------------------------------------------------------------
/src/lj_mcode.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Machine code management.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_MCODE_H
7 | #define _LJ_MCODE_H
8 |
9 | #include "lj_obj.h"
10 |
11 | #if LJ_HASJIT || LJ_HASFFI
12 | LJ_FUNC void lj_mcode_sync(void *start, void *end);
13 | #endif
14 |
15 | #if LJ_HASJIT
16 |
17 | #include "lj_jit.h"
18 |
19 | LJ_FUNC void lj_mcode_free(jit_State *J);
20 | LJ_FUNC MCode *lj_mcode_reserve(jit_State *J, MCode **lim);
21 | LJ_FUNC void lj_mcode_commit(jit_State *J, MCode *m);
22 | LJ_FUNC void lj_mcode_abort(jit_State *J);
23 | LJ_FUNC MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish);
24 | LJ_FUNC_NORET void lj_mcode_limiterr(jit_State *J, size_t need);
25 |
26 | #define lj_mcode_commitbot(J, m) (J->mcbot = (m))
27 |
28 | #endif
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/src/lj_meta.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Metamethod handling.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_META_H
7 | #define _LJ_META_H
8 |
9 | #include "lj_obj.h"
10 |
11 | /* Metamethod handling */
12 | LJ_FUNC void lj_meta_init(lua_State *L);
13 | LJ_FUNC cTValue *lj_meta_cache(GCtab *mt, MMS mm, GCstr *name);
14 | LJ_FUNC cTValue *lj_meta_lookup(lua_State *L, cTValue *o, MMS mm);
15 | #if LJ_HASFFI
16 | LJ_FUNC int lj_meta_tailcall(lua_State *L, cTValue *tv);
17 | #endif
18 |
19 | #define lj_meta_fastg(g, mt, mm) \
20 | ((mt) == NULL ? NULL : ((mt)->nomm & (1u<<(mm))) ? NULL : \
21 | lj_meta_cache(mt, mm, mmname_str(g, mm)))
22 | #define lj_meta_fast(L, mt, mm) lj_meta_fastg(G(L), mt, mm)
23 |
24 | /* C helpers for some instructions, called from assembler VM. */
25 | LJ_FUNCA cTValue *lj_meta_tget(lua_State *L, cTValue *o, cTValue *k);
26 | LJ_FUNCA TValue *lj_meta_tset(lua_State *L, cTValue *o, cTValue *k);
27 | LJ_FUNCA TValue *lj_meta_arith(lua_State *L, TValue *ra, cTValue *rb,
28 | cTValue *rc, BCReg op);
29 | LJ_FUNCA TValue *lj_meta_cat(lua_State *L, TValue *top, int left);
30 | LJ_FUNCA TValue * LJ_FASTCALL lj_meta_len(lua_State *L, cTValue *o);
31 | LJ_FUNCA TValue *lj_meta_equal(lua_State *L, GCobj *o1, GCobj *o2, int ne);
32 | LJ_FUNCA TValue * LJ_FASTCALL lj_meta_equal_cd(lua_State *L, BCIns ins);
33 | LJ_FUNCA TValue *lj_meta_comp(lua_State *L, cTValue *o1, cTValue *o2, int op);
34 | LJ_FUNCA void lj_meta_istype(lua_State *L, BCReg ra, BCReg tp);
35 | LJ_FUNCA void lj_meta_call(lua_State *L, TValue *func, TValue *top);
36 | LJ_FUNCA void LJ_FASTCALL lj_meta_for(lua_State *L, TValue *o);
37 |
38 | #endif
39 |
--------------------------------------------------------------------------------
/src/lj_obj.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Miscellaneous object handling.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #define lj_obj_c
7 | #define LUA_CORE
8 |
9 | #include "lj_obj.h"
10 |
11 | /* Object type names. */
12 | LJ_DATADEF const char *const lj_obj_typename[] = { /* ORDER LUA_T */
13 | "no value", "nil", "boolean", "userdata", "number", "string",
14 | "table", "function", "userdata", "thread", "proto", "cdata"
15 | };
16 |
17 | LJ_DATADEF const char *const lj_obj_itypename[] = { /* ORDER LJ_T */
18 | "nil", "boolean", "boolean", "userdata", "string", "upval", "thread",
19 | "proto", "function", "trace", "cdata", "table", "userdata", "number"
20 | };
21 |
22 | /* Compare two objects without calling metamethods. */
23 | int LJ_FASTCALL lj_obj_equal(cTValue *o1, cTValue *o2)
24 | {
25 | if (itype(o1) == itype(o2)) {
26 | if (tvispri(o1))
27 | return 1;
28 | if (!tvisnum(o1))
29 | return gcrefeq(o1->gcr, o2->gcr);
30 | } else if (!tvisnumber(o1) || !tvisnumber(o2)) {
31 | return 0;
32 | }
33 | return numberVnum(o1) == numberVnum(o2);
34 | }
35 |
36 | /* Return pointer to object or its object data. */
37 | const void * LJ_FASTCALL lj_obj_ptr(global_State *g, cTValue *o)
38 | {
39 | UNUSED(g);
40 | if (tvisudata(o))
41 | return uddata(udataV(o));
42 | else if (tvislightud(o))
43 | return lightudV(g, o);
44 | else if (LJ_HASFFI && tviscdata(o))
45 | return cdataptr(cdataV(o));
46 | else if (tvisgcv(o))
47 | return gcV(o);
48 | else
49 | return NULL;
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/src/lj_opt_dce.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** DCE: Dead Code Elimination. Pre-LOOP only -- ASM already performs DCE.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #define lj_opt_dce_c
7 | #define LUA_CORE
8 |
9 | #include "lj_obj.h"
10 |
11 | #if LJ_HASJIT
12 |
13 | #include "lj_ir.h"
14 | #include "lj_jit.h"
15 | #include "lj_iropt.h"
16 |
17 | /* Some local macros to save typing. Undef'd at the end. */
18 | #define IR(ref) (&J->cur.ir[(ref)])
19 |
20 | /* Scan through all snapshots and mark all referenced instructions. */
21 | static void dce_marksnap(jit_State *J)
22 | {
23 | SnapNo i, nsnap = J->cur.nsnap;
24 | for (i = 0; i < nsnap; i++) {
25 | SnapShot *snap = &J->cur.snap[i];
26 | SnapEntry *map = &J->cur.snapmap[snap->mapofs];
27 | MSize n, nent = snap->nent;
28 | for (n = 0; n < nent; n++) {
29 | IRRef ref = snap_ref(map[n]);
30 | if (ref >= REF_FIRST)
31 | irt_setmark(IR(ref)->t);
32 | }
33 | }
34 | }
35 |
36 | /* Backwards propagate marks. Replace unused instructions with NOPs. */
37 | static void dce_propagate(jit_State *J)
38 | {
39 | IRRef1 *pchain[IR__MAX];
40 | IRRef ins;
41 | uint32_t i;
42 | for (i = 0; i < IR__MAX; i++) pchain[i] = &J->chain[i];
43 | for (ins = J->cur.nins-1; ins >= REF_FIRST; ins--) {
44 | IRIns *ir = IR(ins);
45 | if (irt_ismarked(ir->t)) {
46 | irt_clearmark(ir->t);
47 | } else if (!ir_sideeff(ir)) {
48 | *pchain[ir->o] = ir->prev; /* Reroute original instruction chain. */
49 | lj_ir_nop(ir);
50 | continue;
51 | }
52 | pchain[ir->o] = &ir->prev;
53 | if (ir->op1 >= REF_FIRST) irt_setmark(IR(ir->op1)->t);
54 | if (ir->op2 >= REF_FIRST) irt_setmark(IR(ir->op2)->t);
55 | }
56 | }
57 |
58 | /* Dead Code Elimination.
59 | **
60 | ** First backpropagate marks for all used instructions. Then replace
61 | ** the unused ones with a NOP. Note that compressing the IR to eliminate
62 | ** the NOPs does not pay off.
63 | */
64 | void lj_opt_dce(jit_State *J)
65 | {
66 | if ((J->flags & JIT_F_OPT_DCE)) {
67 | dce_marksnap(J);
68 | dce_propagate(J);
69 | memset(J->bpropcache, 0, sizeof(J->bpropcache)); /* Invalidate cache. */
70 | }
71 | }
72 |
73 | #undef IR
74 |
75 | #endif
76 |
--------------------------------------------------------------------------------
/src/lj_parse.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Lua parser (source code -> bytecode).
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_PARSE_H
7 | #define _LJ_PARSE_H
8 |
9 | #include "lj_obj.h"
10 | #include "lj_lex.h"
11 |
12 | LJ_FUNC GCproto *lj_parse(LexState *ls);
13 | LJ_FUNC GCstr *lj_parse_keepstr(LexState *ls, const char *str, size_t l);
14 | #if LJ_HASFFI
15 | LJ_FUNC void lj_parse_keepcdata(LexState *ls, TValue *tv, GCcdata *cd);
16 | #endif
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/src/lj_prng.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Pseudo-random number generation.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_PRNG_H
7 | #define _LJ_PRNG_H
8 |
9 | #include "lj_def.h"
10 |
11 | LJ_FUNC int LJ_FASTCALL lj_prng_seed_secure(PRNGState *rs);
12 | LJ_FUNC uint64_t LJ_FASTCALL lj_prng_u64(PRNGState *rs);
13 | LJ_FUNC uint64_t LJ_FASTCALL lj_prng_u64d(PRNGState *rs);
14 |
15 | /* This is just the precomputed result of lib_math.c:random_seed(rs, 0.0). */
16 | static LJ_AINLINE void lj_prng_seed_fixed(PRNGState *rs)
17 | {
18 | rs->u[0] = U64x(a0d27757,0a345b8c);
19 | rs->u[1] = U64x(764a296c,5d4aa64f);
20 | rs->u[2] = U64x(51220704,070adeaa);
21 | rs->u[3] = U64x(2a2717b5,a7b7b927);
22 | }
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/src/lj_profile.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Low-overhead profiling.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_PROFILE_H
7 | #define _LJ_PROFILE_H
8 |
9 | #include "lj_obj.h"
10 |
11 | #if LJ_HASPROFILE
12 |
13 | LJ_FUNC void LJ_FASTCALL lj_profile_interpreter(lua_State *L);
14 | #if !LJ_PROFILE_SIGPROF
15 | LJ_FUNC void LJ_FASTCALL lj_profile_hook_enter(global_State *g);
16 | LJ_FUNC void LJ_FASTCALL lj_profile_hook_leave(global_State *g);
17 | #endif
18 |
19 | #endif
20 |
21 | #endif
22 |
--------------------------------------------------------------------------------
/src/lj_record.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Trace recorder (bytecode -> SSA IR).
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_RECORD_H
7 | #define _LJ_RECORD_H
8 |
9 | #include "lj_obj.h"
10 | #include "lj_jit.h"
11 |
12 | #if LJ_HASJIT
13 | /* Context for recording an indexed load/store. */
14 | typedef struct RecordIndex {
15 | TValue tabv; /* Runtime value of table (or indexed object). */
16 | TValue keyv; /* Runtime value of key. */
17 | TValue valv; /* Runtime value of stored value. */
18 | TValue mobjv; /* Runtime value of metamethod object. */
19 | GCtab *mtv; /* Runtime value of metatable object. */
20 | cTValue *oldv; /* Runtime value of previously stored value. */
21 | TRef tab; /* Table (or indexed object) reference. */
22 | TRef key; /* Key reference. */
23 | TRef val; /* Value reference for a store or 0 for a load. */
24 | TRef mt; /* Metatable reference. */
25 | TRef mobj; /* Metamethod object reference. */
26 | int idxchain; /* Index indirections left or 0 for raw lookup. */
27 | } RecordIndex;
28 |
29 | LJ_FUNC int lj_record_objcmp(jit_State *J, TRef a, TRef b,
30 | cTValue *av, cTValue *bv);
31 | LJ_FUNC void lj_record_stop(jit_State *J, TraceLink linktype, TraceNo lnk);
32 | LJ_FUNC TRef lj_record_constify(jit_State *J, cTValue *o);
33 | LJ_FUNC TRef lj_record_vload(jit_State *J, TRef ref, MSize idx, IRType t);
34 |
35 | LJ_FUNC void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs);
36 | LJ_FUNC void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs);
37 | LJ_FUNC void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults);
38 |
39 | LJ_FUNC int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm);
40 | LJ_FUNC TRef lj_record_idx(jit_State *J, RecordIndex *ix);
41 | LJ_FUNC int lj_record_next(jit_State *J, RecordIndex *ix);
42 |
43 | LJ_FUNC void lj_record_ins(jit_State *J);
44 | LJ_FUNC void lj_record_setup(jit_State *J);
45 | #endif
46 |
47 | #endif
48 |
--------------------------------------------------------------------------------
/src/lj_serialize.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Object de/serialization.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_SERIALIZE_H
7 | #define _LJ_SERIALIZE_H
8 |
9 | #include "lj_obj.h"
10 | #include "lj_buf.h"
11 |
12 | #if LJ_HASBUFFER
13 |
14 | #define LJ_SERIALIZE_DEPTH 100 /* Default depth. */
15 |
16 | LJ_FUNC void LJ_FASTCALL lj_serialize_dict_prep_str(lua_State *L, GCtab *dict);
17 | LJ_FUNC void LJ_FASTCALL lj_serialize_dict_prep_mt(lua_State *L, GCtab *dict);
18 | LJ_FUNC SBufExt * LJ_FASTCALL lj_serialize_put(SBufExt *sbx, cTValue *o);
19 | LJ_FUNC char * LJ_FASTCALL lj_serialize_get(SBufExt *sbx, TValue *o);
20 | LJ_FUNC GCstr * LJ_FASTCALL lj_serialize_encode(lua_State *L, cTValue *o);
21 | LJ_FUNC void lj_serialize_decode(lua_State *L, TValue *o, GCstr *str);
22 | #if LJ_HASJIT
23 | LJ_FUNC MSize LJ_FASTCALL lj_serialize_peektype(SBufExt *sbx);
24 | #endif
25 |
26 | #endif
27 |
28 | #endif
29 |
--------------------------------------------------------------------------------
/src/lj_snap.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Snapshot handling.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_SNAP_H
7 | #define _LJ_SNAP_H
8 |
9 | #include "lj_obj.h"
10 | #include "lj_jit.h"
11 |
12 | #if LJ_HASJIT
13 | LJ_FUNC void lj_snap_add(jit_State *J);
14 | LJ_FUNC void lj_snap_purge(jit_State *J);
15 | LJ_FUNC void lj_snap_shrink(jit_State *J);
16 | LJ_FUNC IRIns *lj_snap_regspmap(jit_State *J, GCtrace *T, SnapNo snapno,
17 | IRIns *ir);
18 | LJ_FUNC void lj_snap_replay(jit_State *J, GCtrace *T);
19 | LJ_FUNC const BCIns *lj_snap_restore(jit_State *J, void *exptr);
20 | LJ_FUNC void lj_snap_grow_buf_(jit_State *J, MSize need);
21 | LJ_FUNC void lj_snap_grow_map_(jit_State *J, MSize need);
22 |
23 | static LJ_AINLINE void lj_snap_grow_buf(jit_State *J, MSize need)
24 | {
25 | if (LJ_UNLIKELY(need > J->sizesnap)) lj_snap_grow_buf_(J, need);
26 | }
27 |
28 | static LJ_AINLINE void lj_snap_grow_map(jit_State *J, MSize need)
29 | {
30 | if (LJ_UNLIKELY(need > J->sizesnapmap)) lj_snap_grow_map_(J, need);
31 | }
32 |
33 | #endif
34 |
35 | #endif
36 |
--------------------------------------------------------------------------------
/src/lj_state.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** State and stack handling.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_STATE_H
7 | #define _LJ_STATE_H
8 |
9 | #include "lj_obj.h"
10 |
11 | #define incr_top(L) \
12 | (++L->top >= tvref(L->maxstack) && (lj_state_growstack1(L), 0))
13 |
14 | #define savestack(L, p) ((char *)(p) - mref(L->stack, char))
15 | #define restorestack(L, n) ((TValue *)(mref(L->stack, char) + (n)))
16 |
17 | LJ_FUNC void lj_state_relimitstack(lua_State *L);
18 | LJ_FUNC void lj_state_shrinkstack(lua_State *L, MSize used);
19 | LJ_FUNCA void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need);
20 | LJ_FUNC void LJ_FASTCALL lj_state_growstack1(lua_State *L);
21 | LJ_FUNC int LJ_FASTCALL lj_state_cpgrowstack(lua_State *L, MSize need);
22 |
23 | static LJ_AINLINE void lj_state_checkstack(lua_State *L, MSize need)
24 | {
25 | if ((mref(L->maxstack, char) - (char *)L->top) <=
26 | (ptrdiff_t)need*(ptrdiff_t)sizeof(TValue))
27 | lj_state_growstack(L, need);
28 | }
29 |
30 | LJ_FUNC lua_State *lj_state_new(lua_State *L);
31 | LJ_FUNC void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L);
32 | #if LJ_64 && !LJ_GC64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC))
33 | LJ_FUNC lua_State *lj_state_newstate(lua_Alloc f, void *ud);
34 | #endif
35 |
36 | #define LJ_ALLOCF_INTERNAL ((lua_Alloc)(void *)(uintptr_t)(1237<<4))
37 |
38 | #endif
39 |
--------------------------------------------------------------------------------
/src/lj_str.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** String handling.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_STR_H
7 | #define _LJ_STR_H
8 |
9 | #include
10 |
11 | #include "lj_obj.h"
12 |
13 | /* String helpers. */
14 | LJ_FUNC int32_t LJ_FASTCALL lj_str_cmp(GCstr *a, GCstr *b);
15 | LJ_FUNC const char *lj_str_find(const char *s, const char *f,
16 | MSize slen, MSize flen);
17 | LJ_FUNC int lj_str_haspattern(GCstr *s);
18 |
19 | /* String interning. */
20 | LJ_FUNC void lj_str_resize(lua_State *L, MSize newmask);
21 | LJ_FUNCA GCstr *lj_str_new(lua_State *L, const char *str, size_t len);
22 | LJ_FUNC void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s);
23 | LJ_FUNC void LJ_FASTCALL lj_str_init(lua_State *L);
24 | #define lj_str_freetab(g) \
25 | (lj_mem_freevec(g, g->str.tab, g->str.mask+1, GCRef))
26 |
27 | #define lj_str_newz(L, s) (lj_str_new(L, s, strlen(s)))
28 | #define lj_str_newlit(L, s) (lj_str_new(L, "" s, sizeof(s)-1))
29 | #define lj_str_size(len) (sizeof(GCstr) + (((len)+4) & ~(MSize)3))
30 |
31 | #ifdef LJ_HAS_OPTIMISED_HASH
32 | typedef StrHash (*str_sparse_hashfn) (uint64_t, const char *, MSize);
33 | extern str_sparse_hashfn hash_sparse;
34 |
35 | #if LUAJIT_SECURITY_STRHASH
36 | typedef StrHash (*str_dense_hashfn) (uint64_t, StrHash, const char *, MSize);
37 | extern str_dense_hashfn hash_dense;
38 | #endif
39 |
40 | extern void str_hash_init_sse42 (void);
41 | #endif
42 |
43 | #endif
44 |
--------------------------------------------------------------------------------
/src/lj_strfmt.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** String formatting.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_STRFMT_H
7 | #define _LJ_STRFMT_H
8 |
9 | #include "lj_obj.h"
10 |
11 | typedef uint32_t SFormat; /* Format indicator. */
12 |
13 | /* Format parser state. */
14 | typedef struct FormatState {
15 | const uint8_t *p; /* Current format string pointer. */
16 | const uint8_t *e; /* End of format string. */
17 | const char *str; /* Returned literal string. */
18 | MSize len; /* Size of literal string. */
19 | } FormatState;
20 |
21 | /* Format types (max. 16). */
22 | typedef enum FormatType {
23 | STRFMT_EOF, STRFMT_ERR, STRFMT_LIT,
24 | STRFMT_INT, STRFMT_UINT, STRFMT_NUM, STRFMT_STR, STRFMT_CHAR, STRFMT_PTR
25 | } FormatType;
26 |
27 | /* Format subtypes (bits are reused). */
28 | #define STRFMT_T_HEX 0x0010 /* STRFMT_UINT */
29 | #define STRFMT_T_OCT 0x0020 /* STRFMT_UINT */
30 | #define STRFMT_T_FP_A 0x0000 /* STRFMT_NUM */
31 | #define STRFMT_T_FP_E 0x0010 /* STRFMT_NUM */
32 | #define STRFMT_T_FP_F 0x0020 /* STRFMT_NUM */
33 | #define STRFMT_T_FP_G 0x0030 /* STRFMT_NUM */
34 | #define STRFMT_T_QUOTED 0x0010 /* STRFMT_STR */
35 |
36 | /* Format flags. */
37 | #define STRFMT_F_LEFT 0x0100
38 | #define STRFMT_F_PLUS 0x0200
39 | #define STRFMT_F_ZERO 0x0400
40 | #define STRFMT_F_SPACE 0x0800
41 | #define STRFMT_F_ALT 0x1000
42 | #define STRFMT_F_UPPER 0x2000
43 |
44 | /* Format indicator fields. */
45 | #define STRFMT_SH_WIDTH 16
46 | #define STRFMT_SH_PREC 24
47 |
48 | #define STRFMT_TYPE(sf) ((FormatType)((sf) & 15))
49 | #define STRFMT_WIDTH(sf) (((sf) >> STRFMT_SH_WIDTH) & 255u)
50 | #define STRFMT_PREC(sf) ((((sf) >> STRFMT_SH_PREC) & 255u) - 1u)
51 | #define STRFMT_FP(sf) (((sf) >> 4) & 3)
52 |
53 | /* Formats for conversion characters. */
54 | #define STRFMT_A (STRFMT_NUM|STRFMT_T_FP_A)
55 | #define STRFMT_C (STRFMT_CHAR)
56 | #define STRFMT_D (STRFMT_INT)
57 | #define STRFMT_E (STRFMT_NUM|STRFMT_T_FP_E)
58 | #define STRFMT_F (STRFMT_NUM|STRFMT_T_FP_F)
59 | #define STRFMT_G (STRFMT_NUM|STRFMT_T_FP_G)
60 | #define STRFMT_I STRFMT_D
61 | #define STRFMT_O (STRFMT_UINT|STRFMT_T_OCT)
62 | #define STRFMT_P (STRFMT_PTR)
63 | #define STRFMT_Q (STRFMT_STR|STRFMT_T_QUOTED)
64 | #define STRFMT_S (STRFMT_STR)
65 | #define STRFMT_U (STRFMT_UINT)
66 | #define STRFMT_X (STRFMT_UINT|STRFMT_T_HEX)
67 | #define STRFMT_G14 (STRFMT_G | ((14+1) << STRFMT_SH_PREC))
68 |
69 | /* Maximum buffer sizes for conversions. */
70 | #define STRFMT_MAXBUF_XINT (1+22) /* '0' prefix + uint64_t in octal. */
71 | #define STRFMT_MAXBUF_INT (1+10) /* Sign + int32_t in decimal. */
72 | #define STRFMT_MAXBUF_NUM 32 /* Must correspond with STRFMT_G14. */
73 | #define STRFMT_MAXBUF_PTR (2+2*sizeof(ptrdiff_t)) /* "0x" + hex ptr. */
74 |
75 | /* Format parser. */
76 | LJ_FUNC SFormat LJ_FASTCALL lj_strfmt_parse(FormatState *fs);
77 |
78 | static LJ_AINLINE void lj_strfmt_init(FormatState *fs, const char *p, MSize len)
79 | {
80 | fs->p = (const uint8_t *)p;
81 | fs->e = (const uint8_t *)p + len;
82 | /* Must be NUL-terminated. May have NULs inside, too. */
83 | lj_assertX(*fs->e == 0, "format not NUL-terminated");
84 | }
85 |
86 | /* Raw conversions. */
87 | LJ_FUNC char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k);
88 | LJ_FUNC char * LJ_FASTCALL lj_strfmt_wptr(char *p, const void *v);
89 | LJ_FUNC char * LJ_FASTCALL lj_strfmt_wuleb128(char *p, uint32_t v);
90 | LJ_FUNC const char *lj_strfmt_wstrnum(lua_State *L, cTValue *o, MSize *lenp);
91 |
92 | /* Unformatted conversions to buffer. */
93 | LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putint(SBuf *sb, int32_t k);
94 | #if LJ_HASJIT
95 | LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putnum(SBuf *sb, cTValue *o);
96 | #endif
97 | LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putptr(SBuf *sb, const void *v);
98 | #if LJ_HASJIT
99 | LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putquoted(SBuf *sb, GCstr *str);
100 | #endif
101 |
102 | /* Formatted conversions to buffer. */
103 | LJ_FUNC SBuf *lj_strfmt_putfxint(SBuf *sb, SFormat sf, uint64_t k);
104 | LJ_FUNC SBuf *lj_strfmt_putfnum_int(SBuf *sb, SFormat sf, lua_Number n);
105 | LJ_FUNC SBuf *lj_strfmt_putfnum_uint(SBuf *sb, SFormat sf, lua_Number n);
106 | LJ_FUNC SBuf *lj_strfmt_putfnum(SBuf *sb, SFormat, lua_Number n);
107 | LJ_FUNC SBuf *lj_strfmt_putfchar(SBuf *sb, SFormat, int32_t c);
108 | #if LJ_HASJIT
109 | LJ_FUNC SBuf *lj_strfmt_putfstr(SBuf *sb, SFormat, GCstr *str);
110 | #endif
111 | LJ_FUNC int lj_strfmt_putarg(lua_State *L, SBuf *sb, int arg, int retry);
112 |
113 | /* Conversions to strings. */
114 | LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_int(lua_State *L, int32_t k);
115 | LJ_FUNCA GCstr * LJ_FASTCALL lj_strfmt_num(lua_State *L, cTValue *o);
116 | LJ_FUNCA GCstr * LJ_FASTCALL lj_strfmt_number(lua_State *L, cTValue *o);
117 | #if LJ_HASJIT
118 | LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_char(lua_State *L, int c);
119 | #endif
120 | LJ_FUNC GCstr * LJ_FASTCALL lj_strfmt_obj(lua_State *L, cTValue *o);
121 |
122 | /* Internal string formatting. */
123 | LJ_FUNC const char *lj_strfmt_pushvf(lua_State *L, const char *fmt,
124 | va_list argp);
125 | LJ_FUNC const char *lj_strfmt_pushf(lua_State *L, const char *fmt, ...)
126 | #if defined(__GNUC__) || defined(__clang__)
127 | __attribute__ ((format (printf, 2, 3)))
128 | #endif
129 | ;
130 |
131 | #endif
132 |
--------------------------------------------------------------------------------
/src/lj_strscan.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** String scanning.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_STRSCAN_H
7 | #define _LJ_STRSCAN_H
8 |
9 | #include "lj_obj.h"
10 |
11 | /* Options for accepted/returned formats. */
12 | #define STRSCAN_OPT_TOINT 0x01 /* Convert to int32_t, if possible. */
13 | #define STRSCAN_OPT_TONUM 0x02 /* Always convert to double. */
14 | #define STRSCAN_OPT_IMAG 0x04
15 | #define STRSCAN_OPT_LL 0x08
16 | #define STRSCAN_OPT_C 0x10
17 |
18 | /* Returned format. */
19 | typedef enum {
20 | STRSCAN_ERROR,
21 | STRSCAN_NUM, STRSCAN_IMAG,
22 | STRSCAN_INT, STRSCAN_U32, STRSCAN_I64, STRSCAN_U64,
23 | } StrScanFmt;
24 |
25 | LJ_FUNC StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o,
26 | uint32_t opt);
27 | LJ_FUNC int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o);
28 | #if LJ_DUALNUM
29 | LJ_FUNC int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o);
30 | #else
31 | #define lj_strscan_number(s, o) lj_strscan_num((s), (o))
32 | #endif
33 |
34 | /* Check for number or convert string to number/int in-place (!). */
35 | static LJ_AINLINE int lj_strscan_numberobj(TValue *o)
36 | {
37 | return tvisnumber(o) || (tvisstr(o) && lj_strscan_number(strV(o), o));
38 | }
39 |
40 | #endif
41 |
--------------------------------------------------------------------------------
/src/lj_tab.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Table handling.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_TAB_H
7 | #define _LJ_TAB_H
8 |
9 | #include "lj_obj.h"
10 |
11 | /* Hash constants. Tuned using a brute force search. */
12 | #define HASH_BIAS (-0x04c11db7)
13 | #define HASH_ROT1 14
14 | #define HASH_ROT2 5
15 | #define HASH_ROT3 13
16 |
17 | /* Scramble the bits of numbers and pointers. */
18 | static LJ_AINLINE uint32_t hashrot(uint32_t lo, uint32_t hi)
19 | {
20 | #if LJ_TARGET_X86ORX64
21 | /* Prefer variant that compiles well for a 2-operand CPU. */
22 | lo ^= hi; hi = lj_rol(hi, HASH_ROT1);
23 | lo -= hi; hi = lj_rol(hi, HASH_ROT2);
24 | hi ^= lo; hi -= lj_rol(lo, HASH_ROT3);
25 | #else
26 | lo ^= hi;
27 | lo = lo - lj_rol(hi, HASH_ROT1);
28 | hi = lo ^ lj_rol(hi, HASH_ROT1 + HASH_ROT2);
29 | hi = hi - lj_rol(lo, HASH_ROT3);
30 | #endif
31 | return hi;
32 | }
33 |
34 | /* Hash values are masked with the table hash mask and used as an index. */
35 | static LJ_AINLINE Node *hashmask(const GCtab *t, uint32_t hash)
36 | {
37 | Node *n = noderef(t->node);
38 | return &n[hash & t->hmask];
39 | }
40 |
41 | /* String IDs are generated when a string is interned. */
42 | #define hashstr(t, s) hashmask(t, (s)->sid)
43 |
44 | #define hashlohi(t, lo, hi) hashmask((t), hashrot((lo), (hi)))
45 | #define hashnum(t, o) hashlohi((t), (o)->u32.lo, ((o)->u32.hi << 1))
46 | #if LJ_GC64
47 | #define hashgcref(t, r) \
48 | hashlohi((t), (uint32_t)gcrefu(r), (uint32_t)(gcrefu(r) >> 32))
49 | #else
50 | #define hashgcref(t, r) hashlohi((t), gcrefu(r), gcrefu(r) + HASH_BIAS)
51 | #endif
52 |
53 | #define hsize2hbits(s) ((s) ? ((s)==1 ? 1 : 1+lj_fls((uint32_t)((s)-1))) : 0)
54 |
55 | LJ_FUNCA GCtab *lj_tab_new(lua_State *L, uint32_t asize, uint32_t hbits);
56 | LJ_FUNC GCtab *lj_tab_new_ah(lua_State *L, int32_t a, int32_t h);
57 | #if LJ_HASJIT
58 | LJ_FUNC GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize);
59 | #endif
60 | LJ_FUNCA GCtab * lj_tab_dup_helper(lua_State *L, const GCtab *kt, int is_tab_clone);
61 | LJ_FUNCA GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt);
62 | LJ_FUNC void LJ_FASTCALL lj_tab_clear(GCtab *t);
63 | LJ_FUNC void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t);
64 | LJ_FUNC void lj_tab_resize(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits);
65 | LJ_FUNCA void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize);
66 |
67 | /* Caveat: all getters except lj_tab_get() can return NULL! */
68 |
69 | LJ_FUNCA cTValue * LJ_FASTCALL lj_tab_getinth(GCtab *t, int32_t key);
70 | LJ_FUNC cTValue *lj_tab_getstr(GCtab *t, const GCstr *key);
71 | LJ_FUNCA cTValue *lj_tab_get(lua_State *L, GCtab *t, cTValue *key);
72 |
73 | /* Caveat: all setters require a write barrier for the stored value. */
74 |
75 | LJ_FUNCA TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key);
76 | LJ_FUNCA TValue *lj_tab_setinth(lua_State *L, GCtab *t, int32_t key);
77 | LJ_FUNC TValue *lj_tab_setstr(lua_State *L, GCtab *t, const GCstr *key);
78 | LJ_FUNC TValue *lj_tab_set(lua_State *L, GCtab *t, cTValue *key);
79 |
80 | #define inarray(t, key) ((MSize)(key) < (MSize)(t)->asize)
81 | #define arrayslot(t, i) (&tvref((t)->array)[(i)])
82 | #define lj_tab_getint(t, key) \
83 | (inarray((t), (key)) ? arrayslot((t), (key)) : lj_tab_getinth((t), (key)))
84 | #define lj_tab_setint(L, t, key) \
85 | (inarray((t), (key)) ? arrayslot((t), (key)) : lj_tab_setinth(L, (t), (key)))
86 |
87 | LJ_FUNC uint32_t LJ_FASTCALL lj_tab_keyindex(GCtab *t, cTValue *key);
88 | LJ_FUNCA int lj_tab_next(GCtab *t, cTValue *key, TValue *o);
89 | LJ_FUNCA MSize LJ_FASTCALL lj_tab_len(GCtab *t);
90 | #if LJ_HASJIT
91 | LJ_FUNC MSize LJ_FASTCALL lj_tab_len_hint(GCtab *t, size_t hint);
92 | #endif
93 |
94 | LJ_FUNCA GCtab * LJ_FASTCALL lj_tab_clone(lua_State *L, const GCtab *src);
95 | LJ_FUNCA int LJ_FASTCALL lj_tab_isarray(const GCtab *src);
96 | LJ_FUNCA MSize LJ_FASTCALL lj_tab_nkeys(const GCtab *src);
97 | LJ_FUNCA int LJ_FASTCALL lj_tab_isempty(const GCtab *t);
98 |
99 | #endif
100 |
--------------------------------------------------------------------------------
/src/lj_target_s390x.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Definitions for IBM z/Architecture (s390x) CPUs.
3 | ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_TARGET_S390X_H
7 | #define _LJ_TARGET_S390X_H
8 |
9 | /* -- Registers IDs ------------------------------------------------------- */
10 |
11 | #define GPRDEF(_) \
12 | _(R0) _(R1) _(R2) _(R3) _(R4) _(R5) _(R6) _(R7) \
13 | _(R8) _(R9) _(R10) _(R11) _(R12) _(R13) _(R14) _(R15)
14 | #define FPRDEF(_) \
15 | _(F0) _(F1) _(F2) _(F3) \
16 | _(F4) _(F5) _(F6) _(F7) \
17 | _(F8) _(F9) _(F10) _(F11) \
18 | _(F12) _(F13) _(F14) _(F15)
19 | // TODO: VREG?
20 |
21 | #define RIDENUM(name) RID_##name,
22 |
23 | enum {
24 | GPRDEF(RIDENUM) /* General-purpose registers (GPRs). */
25 | FPRDEF(RIDENUM) /* Floating-point registers (FPRs). */
26 | RID_MAX,
27 |
28 | /* Calling conventions. */
29 | RID_SP = RID_R15,
30 | RID_RET = RID_R2,
31 | RID_FPRET = RID_F0,
32 |
33 | /* These definitions must match with the *.dasc file(s): */
34 | RID_BASE = RID_R7, /* Interpreter BASE. */
35 | RID_LPC = RID_R9, /* Interpreter PC. */
36 | RID_DISPATCH = RID_R10, /* Interpreter DISPATCH table. */
37 |
38 | /* Register ranges [min, max) and number of registers. */
39 | RID_MIN_GPR = RID_R0,
40 | RID_MIN_FPR = RID_F0,
41 | RID_MAX_GPR = RID_MIN_FPR,
42 | RID_MAX_FPR = RID_MAX,
43 | RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR,
44 | RID_NUM_FPR = RID_MAX_FPR - RID_MIN_FPR,
45 | };
46 |
47 | /* -- Register sets ------------------------------------------------------- */
48 |
49 | /* -- Spill slots --------------------------------------------------------- */
50 |
51 | /* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
52 | **
53 | ** SPS_FIXED: Available fixed spill slots in interpreter frame.
54 | ** This definition must match with the *.dasc file(s).
55 | **
56 | ** SPS_FIRST: First spill slot for general use. Reserve min. two 32 bit slots.
57 | */
58 | #define SPS_FIXED 2
59 | #define SPS_FIRST 2
60 |
61 | #define SPOFS_TMP 0
62 |
63 | #define sps_scale(slot) (4 * (int32_t)(slot))
64 | #define sps_align(slot) (((slot) - SPS_FIXED + 1) & ~1)
65 |
66 | /* -- Exit state ---------------------------------------------------------- */
67 |
68 | /* This definition must match with the *.dasc file(s). */
69 | typedef struct {
70 | lua_Number fpr[RID_NUM_FPR]; /* Floating-point registers. */
71 | int32_t gpr[RID_NUM_GPR]; /* General-purpose registers. */
72 | int32_t spill[256]; /* Spill slots. */
73 | } ExitState;
74 |
75 | #define EXITSTUB_SPACING 4
76 | #define EXITSTUBS_PER_GROUP 32
77 |
78 | /* -- Instructions -------------------------------------------------------- */
79 |
80 | #endif
81 |
82 |
--------------------------------------------------------------------------------
/src/lj_trace.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Trace management.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_TRACE_H
7 | #define _LJ_TRACE_H
8 |
9 | #include "lj_obj.h"
10 |
11 | #if LJ_HASJIT
12 | #include "lj_jit.h"
13 | #include "lj_dispatch.h"
14 |
15 | /* Trace errors. */
16 | typedef enum {
17 | #define TREDEF(name, msg) LJ_TRERR_##name,
18 | #include "lj_traceerr.h"
19 | LJ_TRERR__MAX
20 | } TraceError;
21 |
22 | LJ_FUNC_NORET void lj_trace_err(jit_State *J, TraceError e);
23 | LJ_FUNC_NORET void lj_trace_err_info(jit_State *J, TraceError e);
24 |
25 | /* Trace management. */
26 | LJ_FUNC GCtrace * LJ_FASTCALL lj_trace_alloc(lua_State *L, GCtrace *T);
27 | LJ_FUNC void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T);
28 | LJ_FUNC void lj_trace_reenableproto(GCproto *pt);
29 | LJ_FUNC void lj_trace_flushproto(global_State *g, GCproto *pt);
30 | LJ_FUNC void lj_trace_flush(jit_State *J, TraceNo traceno);
31 | LJ_FUNC int lj_trace_flushall(lua_State *L);
32 | LJ_FUNC void lj_trace_initstate(global_State *g);
33 | LJ_FUNC void lj_trace_freestate(global_State *g);
34 |
35 | /* Event handling. */
36 | LJ_FUNC void lj_trace_ins(jit_State *J, const BCIns *pc);
37 | LJ_FUNCA void LJ_FASTCALL lj_trace_hot(jit_State *J, const BCIns *pc);
38 | LJ_FUNCA void LJ_FASTCALL lj_trace_stitch(jit_State *J, const BCIns *pc);
39 | LJ_FUNCA int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr);
40 | #if LJ_UNWIND_EXT
41 | LJ_FUNC uintptr_t LJ_FASTCALL lj_trace_unwind(jit_State *J, uintptr_t addr, ExitNo *ep);
42 | #endif
43 |
44 | /* Signal asynchronous abort of trace or end of trace. */
45 | #define lj_trace_abort(g) (G2J(g)->state &= ~LJ_TRACE_ACTIVE)
46 | #define lj_trace_end(J) (J->state = LJ_TRACE_END)
47 |
48 | #else
49 |
50 | #define lj_trace_flushall(L) (UNUSED(L), 0)
51 | #define lj_trace_initstate(g) UNUSED(g)
52 | #define lj_trace_freestate(g) UNUSED(g)
53 | #define lj_trace_abort(g) UNUSED(g)
54 | #define lj_trace_end(J) UNUSED(J)
55 |
56 | #endif
57 |
58 | #endif
59 |
--------------------------------------------------------------------------------
/src/lj_traceerr.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Trace compiler error messages.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | /* This file may be included multiple times with different TREDEF macros. */
7 |
8 | /* Recording. */
9 | TREDEF(RECERR, "error thrown or hook called during recording")
10 | TREDEF(TRACEUV, "trace too short")
11 | TREDEF(TRACEOV, "trace too long")
12 | TREDEF(STACKOV, "trace too deep")
13 | TREDEF(SNAPOV, "too many snapshots")
14 | TREDEF(BLACKL, "blacklisted")
15 | TREDEF(RETRY, "retry recording")
16 | TREDEF(NYIBC, "NYI: bytecode %s")
17 |
18 | /* Recording loop ops. */
19 | TREDEF(LLEAVE, "leaving loop in root trace")
20 | TREDEF(LINNER, "inner loop in root trace")
21 | TREDEF(LUNROLL, "loop unroll limit reached")
22 |
23 | /* Recording calls/returns. */
24 | TREDEF(BADTYPE, "bad argument type")
25 | TREDEF(CJITOFF, "JIT compilation disabled for function")
26 | TREDEF(CUNROLL, "call unroll limit reached")
27 | TREDEF(DOWNREC, "down-recursion, restarting")
28 | TREDEF(NYIFFU, "NYI: unsupported variant of FastFunc %s")
29 | TREDEF(NYIRETL, "NYI: return to lower frame")
30 |
31 | /* Recording indexed load/store. */
32 | TREDEF(STORENN, "store with nil or NaN key")
33 | TREDEF(NOMM, "missing metamethod")
34 | TREDEF(IDXLOOP, "looping index lookup")
35 | TREDEF(NYITMIX, "NYI: mixed sparse/dense table")
36 |
37 | /* Recording C data operations. */
38 | TREDEF(NOCACHE, "symbol not in cache")
39 | TREDEF(NYICONV, "NYI: unsupported C type conversion")
40 | TREDEF(NYICALL, "NYI: unsupported C function type")
41 |
42 | /* Optimizations. */
43 | TREDEF(GFAIL, "guard would always fail")
44 | TREDEF(PHIOV, "too many PHIs")
45 | TREDEF(TYPEINS, "persistent type instability")
46 |
47 | /* Assembler. */
48 | TREDEF(MCODEAL, "failed to allocate mcode memory")
49 | TREDEF(MCODEOV, "machine code too long")
50 | TREDEF(MCODELM, "hit mcode limit (retrying)")
51 | TREDEF(SPILLOV, "too many spill slots")
52 | TREDEF(BADRA, "inconsistent register allocation")
53 | TREDEF(NYIIR, "NYI: cannot assemble IR instruction %d")
54 | TREDEF(NYIPHI, "NYI: PHI shuffling too complex")
55 | TREDEF(NYICOAL, "NYI: register coalescing too complex")
56 |
57 | #undef TREDEF
58 |
59 | /* Detecting unused error messages:
60 | awk -F, '/^TREDEF/ { gsub(/TREDEF./, ""); printf "grep -q LJ_TRERR_%s *.[ch] || echo %s\n", $1, $1}' lj_traceerr.h | sh
61 | */
62 |
--------------------------------------------------------------------------------
/src/lj_udata.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Userdata handling.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #define lj_udata_c
7 | #define LUA_CORE
8 |
9 | #include "lj_obj.h"
10 | #include "lj_gc.h"
11 | #include "lj_err.h"
12 | #include "lj_udata.h"
13 |
14 | GCudata *lj_udata_new(lua_State *L, MSize sz, GCtab *env)
15 | {
16 | GCudata *ud = lj_mem_newt(L, sizeof(GCudata) + sz, GCudata);
17 | global_State *g = G(L);
18 | newwhite(g, ud); /* Not finalized. */
19 | ud->gct = ~LJ_TUDATA;
20 | ud->udtype = UDTYPE_USERDATA;
21 | ud->len = sz;
22 | /* NOBARRIER: The GCudata is new (marked white). */
23 | setgcrefnull(ud->metatable);
24 | setgcref(ud->env, obj2gco(env));
25 | /* Chain to userdata list (after main thread). */
26 | setgcrefr(ud->nextgc, mainthread(g)->nextgc);
27 | setgcref(mainthread(g)->nextgc, obj2gco(ud));
28 | return ud;
29 | }
30 |
31 | void LJ_FASTCALL lj_udata_free(global_State *g, GCudata *ud)
32 | {
33 | lj_mem_free(g, ud, sizeudata(ud));
34 | }
35 |
36 | #if LJ_64
37 | void *lj_lightud_intern(lua_State *L, void *p)
38 | {
39 | global_State *g = G(L);
40 | uint64_t u = (uint64_t)p;
41 | uint32_t up = lightudup(u);
42 | uint32_t *segmap = mref(g->gc.lightudseg, uint32_t);
43 | MSize segnum = g->gc.lightudnum;
44 | if (segmap) {
45 | MSize seg;
46 | for (seg = 0; seg <= segnum; seg++)
47 | if (segmap[seg] == up) /* Fast path. */
48 | return (void *)(((uint64_t)seg << LJ_LIGHTUD_BITS_LO) | lightudlo(u));
49 | segnum++;
50 | /* Leave last segment unused to avoid clash with ITERN key. */
51 | if (segnum >= (1 << LJ_LIGHTUD_BITS_SEG)-1) lj_err_msg(L, LJ_ERR_BADLU);
52 | }
53 | if (!((segnum-1) & segnum) && segnum != 1) {
54 | lj_mem_reallocvec(L, segmap, segnum, segnum ? 2*segnum : 2u, uint32_t);
55 | setmref(g->gc.lightudseg, segmap);
56 | }
57 | g->gc.lightudnum = segnum;
58 | segmap[segnum] = up;
59 | return (void *)(((uint64_t)segnum << LJ_LIGHTUD_BITS_LO) | lightudlo(u));
60 | }
61 | #endif
62 |
63 |
--------------------------------------------------------------------------------
/src/lj_udata.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Userdata handling.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_UDATA_H
7 | #define _LJ_UDATA_H
8 |
9 | #include "lj_obj.h"
10 |
11 | LJ_FUNC GCudata *lj_udata_new(lua_State *L, MSize sz, GCtab *env);
12 | LJ_FUNC void LJ_FASTCALL lj_udata_free(global_State *g, GCudata *ud);
13 | #if LJ_64
14 | LJ_FUNC void * LJ_FASTCALL lj_lightud_intern(lua_State *L, void *p);
15 | #endif
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/src/lj_vm.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Assembler VM interface definitions.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_VM_H
7 | #define _LJ_VM_H
8 |
9 | #include "lj_obj.h"
10 |
11 | /* Entry points for ASM parts of VM. */
12 | LJ_ASMF void lj_vm_call(lua_State *L, TValue *base, int nres1);
13 | LJ_ASMF int lj_vm_pcall(lua_State *L, TValue *base, int nres1, ptrdiff_t ef);
14 | typedef TValue *(*lua_CPFunction)(lua_State *L, lua_CFunction func, void *ud);
15 | LJ_ASMF int lj_vm_cpcall(lua_State *L, lua_CFunction func, void *ud,
16 | lua_CPFunction cp);
17 | LJ_ASMF int lj_vm_resume(lua_State *L, TValue *base, int nres1, ptrdiff_t ef);
18 | LJ_ASMF_NORET void LJ_FASTCALL lj_vm_unwind_c(void *cframe, int errcode);
19 | LJ_ASMF_NORET void LJ_FASTCALL lj_vm_unwind_ff(void *cframe);
20 | #if LJ_ABI_WIN && LJ_TARGET_X86
21 | LJ_ASMF_NORET void LJ_FASTCALL lj_vm_rtlunwind(void *cframe, void *excptrec,
22 | void *unwinder, int errcode);
23 | #endif
24 | LJ_ASMF void lj_vm_unwind_c_eh(void);
25 | LJ_ASMF void lj_vm_unwind_ff_eh(void);
26 | #if LJ_TARGET_X86ORX64
27 | LJ_ASMF void lj_vm_unwind_rethrow(void);
28 | #endif
29 | #if LJ_TARGET_MIPS
30 | LJ_ASMF void lj_vm_unwind_stub(void);
31 | #endif
32 |
33 | /* Miscellaneous functions. */
34 | #if LJ_TARGET_X86ORX64
35 | LJ_ASMF int lj_vm_cpuid(uint32_t f, uint32_t res[4]);
36 | #endif
37 | #if LJ_TARGET_PPC
38 | void lj_vm_cachesync(void *start, void *end);
39 | #endif
40 | LJ_ASMF double lj_vm_foldarith(double x, double y, int op);
41 | #if LJ_HASJIT
42 | LJ_ASMF double lj_vm_foldfpm(double x, int op);
43 | #endif
44 | #if !LJ_ARCH_HASFPU
45 | /* Declared in lj_obj.h: LJ_ASMF int32_t lj_vm_tobit(double x); */
46 | #endif
47 |
48 | /* Dispatch targets for recording and hooks. */
49 | LJ_ASMF void lj_vm_record(void);
50 | LJ_ASMF void lj_vm_inshook(void);
51 | LJ_ASMF void lj_vm_rethook(void);
52 | LJ_ASMF void lj_vm_callhook(void);
53 | LJ_ASMF void lj_vm_profhook(void);
54 | LJ_ASMF void lj_vm_IITERN(void);
55 |
56 | /* Trace exit handling. */
57 | LJ_ASMF char lj_vm_exit_handler[];
58 | LJ_ASMF char lj_vm_exit_interp[];
59 |
60 | /* Internal math helper functions. */
61 | #if LJ_TARGET_PPC || LJ_TARGET_ARM64 || (LJ_TARGET_MIPS && LJ_ABI_SOFTFP)
62 | #define lj_vm_floor floor
63 | #define lj_vm_ceil ceil
64 | #else
65 | LJ_ASMF double lj_vm_floor(double);
66 | LJ_ASMF double lj_vm_ceil(double);
67 | #if LJ_TARGET_ARM
68 | LJ_ASMF double lj_vm_floor_sf(double);
69 | LJ_ASMF double lj_vm_ceil_sf(double);
70 | #endif
71 | #endif
72 | #ifdef LUAJIT_NO_LOG2
73 | LJ_ASMF double lj_vm_log2(double);
74 | #else
75 | #define lj_vm_log2 log2
76 | #endif
77 | #if !(defined(_LJ_DISPATCH_H) && LJ_TARGET_MIPS)
78 | LJ_ASMF int32_t LJ_FASTCALL lj_vm_modi(int32_t, int32_t);
79 | #endif
80 |
81 | #if LJ_HASJIT
82 | #if LJ_TARGET_X86ORX64
83 | LJ_ASMF void lj_vm_floor_sse(void);
84 | LJ_ASMF void lj_vm_ceil_sse(void);
85 | LJ_ASMF void lj_vm_trunc_sse(void);
86 | #endif
87 | #if LJ_TARGET_PPC || LJ_TARGET_ARM64
88 | #define lj_vm_trunc trunc
89 | #else
90 | LJ_ASMF double lj_vm_trunc(double);
91 | #if LJ_TARGET_ARM
92 | LJ_ASMF double lj_vm_trunc_sf(double);
93 | #endif
94 | #endif
95 | #if LJ_HASFFI
96 | LJ_ASMF int lj_vm_errno(void);
97 | #endif
98 | LJ_ASMF TValue *lj_vm_next(GCtab *t, uint32_t idx);
99 | #endif
100 |
101 | /* Continuations for metamethods. */
102 | LJ_ASMF void lj_cont_cat(void); /* Continue with concatenation. */
103 | LJ_ASMF void lj_cont_ra(void); /* Store result in RA from instruction. */
104 | LJ_ASMF void lj_cont_nop(void); /* Do nothing, just continue execution. */
105 | LJ_ASMF void lj_cont_condt(void); /* Branch if result is true. */
106 | LJ_ASMF void lj_cont_condf(void); /* Branch if result is false. */
107 | LJ_ASMF void lj_cont_hook(void); /* Continue from hook yield. */
108 | LJ_ASMF void lj_cont_stitch(void); /* Trace stitching. */
109 |
110 | /* Start of the ASM code. */
111 | LJ_ASMF char lj_vm_asm_begin[];
112 |
113 | /* Bytecode offsets are relative to lj_vm_asm_begin. */
114 | #define makeasmfunc(ofs) lj_ptr_sign((ASMFunction)(lj_vm_asm_begin + (ofs)), 0)
115 |
116 | #endif
117 |
--------------------------------------------------------------------------------
/src/lj_vmevent.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** VM event handling.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #include
7 |
8 | #define lj_vmevent_c
9 | #define LUA_CORE
10 |
11 | #include "lj_obj.h"
12 | #include "lj_str.h"
13 | #include "lj_tab.h"
14 | #include "lj_state.h"
15 | #include "lj_dispatch.h"
16 | #include "lj_vm.h"
17 | #include "lj_vmevent.h"
18 |
19 | ptrdiff_t lj_vmevent_prepare(lua_State *L, VMEvent ev)
20 | {
21 | global_State *g = G(L);
22 | GCstr *s = lj_str_newlit(L, LJ_VMEVENTS_REGKEY);
23 | cTValue *tv = lj_tab_getstr(tabV(registry(L)), s);
24 | if (tvistab(tv)) {
25 | int hash = VMEVENT_HASH(ev);
26 | tv = lj_tab_getint(tabV(tv), hash);
27 | if (tv && tvisfunc(tv)) {
28 | lj_state_checkstack(L, LUA_MINSTACK);
29 | setfuncV(L, L->top++, funcV(tv));
30 | if (LJ_FR2) setnilV(L->top++);
31 | return savestack(L, L->top);
32 | }
33 | }
34 | g->vmevmask &= ~VMEVENT_MASK(ev); /* No handler: cache this fact. */
35 | return 0;
36 | }
37 |
38 | void lj_vmevent_call(lua_State *L, ptrdiff_t argbase)
39 | {
40 | global_State *g = G(L);
41 | uint8_t oldmask = g->vmevmask;
42 | uint8_t oldh = hook_save(g);
43 | int status;
44 | g->vmevmask = 0; /* Disable all events. */
45 | hook_vmevent(g);
46 | status = lj_vm_pcall(L, restorestack(L, argbase), 0+1, 0);
47 | if (LJ_UNLIKELY(status)) {
48 | /* Really shouldn't use stderr here, but where else to complain? */
49 | L->top--;
50 | fputs("VM handler failed: ", stderr);
51 | fputs(tvisstr(L->top) ? strVdata(L->top) : "?", stderr);
52 | fputc('\n', stderr);
53 | }
54 | hook_restore(g, oldh);
55 | if (g->vmevmask != VMEVENT_NOCACHE)
56 | g->vmevmask = oldmask; /* Restore event mask, but not if not modified. */
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/src/lj_vmevent.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** VM event handling.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LJ_VMEVENT_H
7 | #define _LJ_VMEVENT_H
8 |
9 | #include "lj_obj.h"
10 |
11 | /* Registry key for VM event handler table. */
12 | #define LJ_VMEVENTS_REGKEY "_VMEVENTS"
13 | #define LJ_VMEVENTS_HSIZE 4
14 |
15 | #define VMEVENT_MASK(ev) ((uint8_t)1 << ((int)(ev) & 7))
16 | #define VMEVENT_HASH(ev) ((int)(ev) & ~7)
17 | #define VMEVENT_HASHIDX(h) ((int)(h) << 3)
18 | #define VMEVENT_NOCACHE 255
19 |
20 | #define VMEVENT_DEF(name, hash) \
21 | LJ_VMEVENT_##name##_, \
22 | LJ_VMEVENT_##name = ((LJ_VMEVENT_##name##_) & 7)|((hash) << 3)
23 |
24 | /* VM event IDs. */
25 | typedef enum {
26 | VMEVENT_DEF(BC, 0x00003883),
27 | VMEVENT_DEF(TRACE, 0x12d91467),
28 | VMEVENT_DEF(RECORD, 0x1284bf4f),
29 | VMEVENT_DEF(TEXIT, 0x129df2b0),
30 | VMEVENT_DEF(ERRFIN, 0x12d93888),
31 | LJ_VMEVENT__MAX
32 | } VMEvent;
33 |
34 | #ifdef LUAJIT_DISABLE_VMEVENT
35 | #define lj_vmevent_send(L, ev, args) UNUSED(L)
36 | #define lj_vmevent_send_(L, ev, args, post) UNUSED(L)
37 | #else
38 | #define lj_vmevent_send(L, ev, args) \
39 | if (G(L)->vmevmask & VMEVENT_MASK(LJ_VMEVENT_##ev)) { \
40 | ptrdiff_t argbase = lj_vmevent_prepare(L, LJ_VMEVENT_##ev); \
41 | if (argbase) { \
42 | args \
43 | lj_vmevent_call(L, argbase); \
44 | } \
45 | }
46 | #define lj_vmevent_send_(L, ev, args, post) \
47 | if (G(L)->vmevmask & VMEVENT_MASK(LJ_VMEVENT_##ev)) { \
48 | ptrdiff_t argbase = lj_vmevent_prepare(L, LJ_VMEVENT_##ev); \
49 | if (argbase) { \
50 | args \
51 | lj_vmevent_call(L, argbase); \
52 | post \
53 | } \
54 | }
55 |
56 | LJ_FUNC ptrdiff_t lj_vmevent_prepare(lua_State *L, VMEvent ev);
57 | LJ_FUNC void lj_vmevent_call(lua_State *L, ptrdiff_t argbase);
58 | #endif
59 |
60 | #endif
61 |
--------------------------------------------------------------------------------
/src/lj_vmmath.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Math helper functions for assembler VM.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #define lj_vmmath_c
7 | #define LUA_CORE
8 |
9 | #include
10 | #include
11 |
12 | #include "lj_obj.h"
13 | #include "lj_ir.h"
14 | #include "lj_vm.h"
15 |
16 | /* -- Wrapper functions --------------------------------------------------- */
17 |
18 | #if LJ_TARGET_X86 && __ELF__ && __PIC__
19 | /* Wrapper functions to deal with the ELF/x86 PIC disaster. */
20 | LJ_FUNCA double lj_wrap_log(double x) { return log(x); }
21 | LJ_FUNCA double lj_wrap_log10(double x) { return log10(x); }
22 | LJ_FUNCA double lj_wrap_exp(double x) { return exp(x); }
23 | LJ_FUNCA double lj_wrap_sin(double x) { return sin(x); }
24 | LJ_FUNCA double lj_wrap_cos(double x) { return cos(x); }
25 | LJ_FUNCA double lj_wrap_tan(double x) { return tan(x); }
26 | LJ_FUNCA double lj_wrap_asin(double x) { return asin(x); }
27 | LJ_FUNCA double lj_wrap_acos(double x) { return acos(x); }
28 | LJ_FUNCA double lj_wrap_atan(double x) { return atan(x); }
29 | LJ_FUNCA double lj_wrap_sinh(double x) { return sinh(x); }
30 | LJ_FUNCA double lj_wrap_cosh(double x) { return cosh(x); }
31 | LJ_FUNCA double lj_wrap_tanh(double x) { return tanh(x); }
32 | LJ_FUNCA double lj_wrap_atan2(double x, double y) { return atan2(x, y); }
33 | LJ_FUNCA double lj_wrap_pow(double x, double y) { return pow(x, y); }
34 | LJ_FUNCA double lj_wrap_fmod(double x, double y) { return fmod(x, y); }
35 | #endif
36 |
37 | /* -- Helper functions ---------------------------------------------------- */
38 |
39 | /* Required to prevent the C compiler from applying FMA optimizations.
40 | **
41 | ** Yes, there's -ffp-contract and the FP_CONTRACT pragma ... in theory.
42 | ** But the current state of C compilers is a mess in this regard.
43 | ** Also, this function is not performance sensitive at all.
44 | */
45 | LJ_NOINLINE static double lj_vm_floormul(double x, double y)
46 | {
47 | return lj_vm_floor(x / y) * y;
48 | }
49 |
50 | double lj_vm_foldarith(double x, double y, int op)
51 | {
52 | switch (op) {
53 | case IR_ADD - IR_ADD: return x+y; break;
54 | case IR_SUB - IR_ADD: return x-y; break;
55 | case IR_MUL - IR_ADD: return x*y; break;
56 | case IR_DIV - IR_ADD: return x/y; break;
57 | case IR_MOD - IR_ADD: return x-lj_vm_floormul(x, y); break;
58 | case IR_POW - IR_ADD: return pow(x, y); break;
59 | case IR_NEG - IR_ADD: return -x; break;
60 | case IR_ABS - IR_ADD: return fabs(x); break;
61 | #if LJ_HASJIT
62 | case IR_LDEXP - IR_ADD: return ldexp(x, (int)y); break;
63 | case IR_MIN - IR_ADD: return x < y ? x : y; break;
64 | case IR_MAX - IR_ADD: return x > y ? x : y; break;
65 | #endif
66 | default: return x;
67 | }
68 | }
69 |
70 | /* -- Helper functions for generated machine code ------------------------- */
71 |
72 | #if (LJ_HASJIT && !(LJ_TARGET_ARM || LJ_TARGET_ARM64 || LJ_TARGET_PPC)) || LJ_TARGET_MIPS
73 | int32_t LJ_FASTCALL lj_vm_modi(int32_t a, int32_t b)
74 | {
75 | uint32_t y, ua, ub;
76 | /* This must be checked before using this function. */
77 | lj_assertX(b != 0, "modulo with zero divisor");
78 | ua = a < 0 ? ~(uint32_t)a+1u : (uint32_t)a;
79 | ub = b < 0 ? ~(uint32_t)b+1u : (uint32_t)b;
80 | y = ua % ub;
81 | if (y != 0 && (a^b) < 0) y = y - ub;
82 | if (((int32_t)y^b) < 0) y = ~y+1u;
83 | return (int32_t)y;
84 | }
85 | #endif
86 |
87 | #if LJ_HASJIT
88 |
89 | #ifdef LUAJIT_NO_LOG2
90 | double lj_vm_log2(double a)
91 | {
92 | return log(a) * 1.4426950408889634074;
93 | }
94 | #endif
95 |
96 | /* Computes fpm(x) for extended math functions. */
97 | double lj_vm_foldfpm(double x, int fpm)
98 | {
99 | switch (fpm) {
100 | case IRFPM_FLOOR: return lj_vm_floor(x);
101 | case IRFPM_CEIL: return lj_vm_ceil(x);
102 | case IRFPM_TRUNC: return lj_vm_trunc(x);
103 | case IRFPM_SQRT: return sqrt(x);
104 | case IRFPM_LOG: return log(x);
105 | case IRFPM_LOG2: return lj_vm_log2(x);
106 | default: lj_assertX(0, "bad fpm %d", fpm);
107 | }
108 | return 0;
109 | }
110 |
111 | #if LJ_HASFFI
112 | int lj_vm_errno(void)
113 | {
114 | return errno;
115 | }
116 | #endif
117 |
118 | #endif
119 |
--------------------------------------------------------------------------------
/src/ljamalg.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** LuaJIT core and libraries amalgamation.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #define ljamalg_c
7 | #define LUA_CORE
8 |
9 | /* To get the mremap prototype. Must be defined before any system includes. */
10 | #if defined(__linux__) && !defined(_GNU_SOURCE)
11 | #define _GNU_SOURCE
12 | #endif
13 |
14 | #ifndef WINVER
15 | #define WINVER 0x0501
16 | #endif
17 |
18 | #include "lua.h"
19 | #include "lauxlib.h"
20 |
21 | #include "lj_assert.c"
22 | #include "lj_gc.c"
23 | #include "lj_err.c"
24 | #include "lj_char.c"
25 | #include "lj_bc.c"
26 | #include "lj_obj.c"
27 | #include "lj_buf.c"
28 | #include "lj_str.c"
29 | #include "lj_tab.c"
30 | #include "lj_func.c"
31 | #include "lj_udata.c"
32 | #include "lj_meta.c"
33 | #include "lj_debug.c"
34 | #include "lj_prng.c"
35 | #include "lj_state.c"
36 | #include "lj_dispatch.c"
37 | #include "lj_vmevent.c"
38 | #include "lj_vmmath.c"
39 | #include "lj_strscan.c"
40 | #include "lj_strfmt.c"
41 | #include "lj_strfmt_num.c"
42 | #include "lj_serialize.c"
43 | #include "lj_api.c"
44 | #include "lj_profile.c"
45 | #include "lj_lex.c"
46 | #include "lj_parse.c"
47 | #include "lj_bcread.c"
48 | #include "lj_bcwrite.c"
49 | #include "lj_load.c"
50 | #include "lj_ctype.c"
51 | #include "lj_cdata.c"
52 | #include "lj_cconv.c"
53 | #include "lj_ccall.c"
54 | #include "lj_ccallback.c"
55 | #include "lj_carith.c"
56 | #include "lj_clib.c"
57 | #include "lj_cparse.c"
58 | #include "lj_lib.c"
59 | #include "lj_ir.c"
60 | #include "lj_opt_mem.c"
61 | #include "lj_opt_fold.c"
62 | #include "lj_opt_narrow.c"
63 | #include "lj_opt_dce.c"
64 | #include "lj_opt_loop.c"
65 | #include "lj_opt_split.c"
66 | #include "lj_opt_sink.c"
67 | #include "lj_mcode.c"
68 | #include "lj_snap.c"
69 | #include "lj_record.c"
70 | #include "lj_crecord.c"
71 | #include "lj_ffrecord.c"
72 | #include "lj_asm.c"
73 | #include "lj_trace.c"
74 | #include "lj_gdbjit.c"
75 | #include "lj_alloc.c"
76 |
77 | #include "lib_aux.c"
78 | #include "lib_base.c"
79 | #include "lib_math.c"
80 | #include "lib_string.c"
81 | #include "lib_table.c"
82 | #include "lib_io.c"
83 | #include "lib_os.c"
84 | #include "lib_package.c"
85 | #include "lib_debug.c"
86 | #include "lib_bit.c"
87 | #include "lib_jit.c"
88 | #include "lib_ffi.c"
89 | #include "lib_buffer.c"
90 | #include "lib_init.c"
91 |
--------------------------------------------------------------------------------
/src/lua.hpp:
--------------------------------------------------------------------------------
1 | // C++ wrapper for LuaJIT header files.
2 |
3 | extern "C" {
4 | #include "lua.h"
5 | #include "lauxlib.h"
6 | #include "lualib.h"
7 | #include "luajit.h"
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/src/luaconf.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Configuration header.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef luaconf_h
7 | #define luaconf_h
8 |
9 | #ifndef WINVER
10 | #define WINVER 0x0501
11 | #endif
12 | #include
13 |
14 | /* Default path for loading Lua and C modules with require(). */
15 | #if defined(_WIN32)
16 | /*
17 | ** In Windows, any exclamation mark ('!') in the path is replaced by the
18 | ** path of the directory of the executable file of the current process.
19 | */
20 | #define LUA_LDIR "!\\lua\\"
21 | #define LUA_CDIR "!\\"
22 | #define LUA_PATH_DEFAULT \
23 | ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;"
24 | #define LUA_CPATH_DEFAULT \
25 | ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
26 | #else
27 | /*
28 | ** Note to distribution maintainers: do NOT patch the following lines!
29 | ** Please read ../doc/install.html#distro and pass PREFIX=/usr instead.
30 | */
31 | #ifndef LUA_MULTILIB
32 | #define LUA_MULTILIB "lib"
33 | #endif
34 | #ifndef LUA_LMULTILIB
35 | #define LUA_LMULTILIB "lib"
36 | #endif
37 | #define LUA_LROOT "/usr/local"
38 | #define LUA_LUADIR "/lua/5.1/"
39 |
40 | #ifdef LUA_ROOT
41 | #define LUA_JROOT LUA_ROOT
42 | #define LUA_RLDIR LUA_ROOT "/share" LUA_LUADIR
43 | #define LUA_RCDIR LUA_ROOT "/" LUA_MULTILIB LUA_LUADIR
44 | #define LUA_RLPATH ";" LUA_RLDIR "?.lua;" LUA_RLDIR "?/init.lua"
45 | #define LUA_RCPATH ";" LUA_RCDIR "?.so"
46 | #else
47 | #define LUA_JROOT LUA_LROOT
48 | #define LUA_RLPATH
49 | #define LUA_RCPATH
50 | #endif
51 |
52 | #ifndef LUA_LJDIR
53 | #define LUA_LJDIR LUA_JROOT "/share/luajit-2.1"
54 | #endif
55 |
56 | #define LUA_JPATH ";" LUA_LJDIR "/?.lua"
57 | #define LUA_LLDIR LUA_LROOT "/share" LUA_LUADIR
58 | #define LUA_LCDIR LUA_LROOT "/" LUA_LMULTILIB LUA_LUADIR
59 | #define LUA_LLPATH ";" LUA_LLDIR "?.lua;" LUA_LLDIR "?/init.lua"
60 | #define LUA_LCPATH1 ";" LUA_LCDIR "?.so"
61 | #define LUA_LCPATH2 ";" LUA_LCDIR "loadall.so"
62 |
63 | #define LUA_PATH_DEFAULT "./?.lua" LUA_JPATH LUA_LLPATH LUA_RLPATH
64 | #define LUA_CPATH_DEFAULT "./?.so" LUA_LCPATH1 LUA_RCPATH LUA_LCPATH2
65 | #endif
66 |
67 | /* Environment variable names for path overrides and initialization code. */
68 | #define LUA_PATH "LUA_PATH"
69 | #define LUA_CPATH "LUA_CPATH"
70 | #define LUA_INIT "LUA_INIT"
71 |
72 | /* Special file system characters. */
73 | #if defined(_WIN32)
74 | #define LUA_DIRSEP "\\"
75 | #else
76 | #define LUA_DIRSEP "/"
77 | #endif
78 | #define LUA_PATHSEP ";"
79 | #define LUA_PATH_MARK "?"
80 | #define LUA_EXECDIR "!"
81 | #define LUA_IGMARK "-"
82 | #define LUA_PATH_CONFIG \
83 | LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" \
84 | LUA_EXECDIR "\n" LUA_IGMARK "\n"
85 |
86 | /* Quoting in error messages. */
87 | #define LUA_QL(x) "'" x "'"
88 | #define LUA_QS LUA_QL("%s")
89 |
90 | /* Various tunables. */
91 | #define LUAI_MAXSTACK 65500 /* Max. # of stack slots for a thread (<64K). */
92 | #define LUAI_MAXCSTACK 8000 /* Max. # of stack slots for a C func (<10K). */
93 | #define LUAI_GCPAUSE 200 /* Pause GC until memory is at 200%. */
94 | #define LUAI_GCMUL 200 /* Run GC at 200% of allocation speed. */
95 | #define LUA_MAXCAPTURES 32 /* Max. pattern captures. */
96 |
97 | /* Configuration for the frontend (the luajit executable). */
98 | #if defined(luajit_c)
99 | #define LUA_PROGNAME "luajit" /* Fallback frontend name. */
100 | #define LUA_PROMPT "> " /* Interactive prompt. */
101 | #define LUA_PROMPT2 ">> " /* Continuation prompt. */
102 | #define LUA_MAXINPUT 512 /* Max. input line length. */
103 | #endif
104 |
105 | /* Note: changing the following defines breaks the Lua 5.1 ABI. */
106 | #define LUA_INTEGER ptrdiff_t
107 | #define LUA_IDSIZE 60 /* Size of lua_Debug.short_src. */
108 | /*
109 | ** Size of lauxlib and io.* on-stack buffers. Weird workaround to avoid using
110 | ** unreasonable amounts of stack space, but still retain ABI compatibility.
111 | ** Blame Lua for depending on BUFSIZ in the ABI, blame **** for wrecking it.
112 | */
113 | #define LUAL_BUFFERSIZE (BUFSIZ > 16384 ? 8192 : BUFSIZ)
114 |
115 | /* The following defines are here only for compatibility with luaconf.h
116 | ** from the standard Lua distribution. They must not be changed for LuaJIT.
117 | */
118 | #define LUA_NUMBER_DOUBLE
119 | #define LUA_NUMBER double
120 | #define LUAI_UACNUMBER double
121 | #define LUA_NUMBER_SCAN "%lf"
122 | #define LUA_NUMBER_FMT "%.14g"
123 | #define lua_number2str(s, n) sprintf((s), LUA_NUMBER_FMT, (n))
124 | #define LUAI_MAXNUMBER2STR 32
125 | #define LUA_INTFRMLEN "l"
126 | #define LUA_INTFRM_T long
127 |
128 | /* Linkage of public API functions. */
129 | #if defined(LUA_BUILD_AS_DLL)
130 | #if defined(LUA_CORE) || defined(LUA_LIB)
131 | #define LUA_API __declspec(dllexport)
132 | #else
133 | #define LUA_API __declspec(dllimport)
134 | #endif
135 | #else
136 | #define LUA_API extern
137 | #endif
138 |
139 | #define LUALIB_API LUA_API
140 |
141 | /* Compatibility support for assertions. */
142 | #if defined(LUA_USE_ASSERT) || defined(LUA_USE_APICHECK)
143 | #include
144 | #endif
145 | #ifdef LUA_USE_ASSERT
146 | #define lua_assert(x) assert(x)
147 | #endif
148 | #ifdef LUA_USE_APICHECK
149 | #define luai_apicheck(L, o) { (void)L; assert(o); }
150 | #else
151 | #define luai_apicheck(L, o) { (void)L; }
152 | #endif
153 |
154 | #endif
155 |
--------------------------------------------------------------------------------
/src/luajit_rolling.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** LuaJIT -- a Just-In-Time Compiler for Lua. https://luajit.org/
3 | **
4 | ** Copyright (C) 2005-2025 Mike Pall. All rights reserved.
5 | **
6 | ** Permission is hereby granted, free of charge, to any person obtaining
7 | ** a copy of this software and associated documentation files (the
8 | ** "Software"), to deal in the Software without restriction, including
9 | ** without limitation the rights to use, copy, modify, merge, publish,
10 | ** distribute, sublicense, and/or sell copies of the Software, and to
11 | ** permit persons to whom the Software is furnished to do so, subject to
12 | ** the following conditions:
13 | **
14 | ** The above copyright notice and this permission notice shall be
15 | ** included in all copies or substantial portions of the Software.
16 | **
17 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 | **
25 | ** [ MIT license: https://www.opensource.org/licenses/mit-license.php ]
26 | */
27 |
28 | #ifndef _LUAJIT_H
29 | #define _LUAJIT_H
30 |
31 | #include "lua.h"
32 |
33 | #define OPENRESTY_LUAJIT
34 |
35 | #define LUAJIT_VERSION "LuaJIT 2.1.ROLLING"
36 | #define LUAJIT_VERSION_NUM 20199 /* Deprecated. */
37 | #define LUAJIT_VERSION_SYM luaJIT_version_2_1_ROLLING
38 | #define LUAJIT_COPYRIGHT "Copyright (C) 2005-2025 Mike Pall"
39 | #define LUAJIT_URL "https://luajit.org/"
40 |
41 | /* Modes for luaJIT_setmode. */
42 | #define LUAJIT_MODE_MASK 0x00ff
43 |
44 | enum {
45 | LUAJIT_MODE_ENGINE, /* Set mode for whole JIT engine. */
46 | LUAJIT_MODE_DEBUG, /* Set debug mode (idx = level). */
47 |
48 | LUAJIT_MODE_FUNC, /* Change mode for a function. */
49 | LUAJIT_MODE_ALLFUNC, /* Recurse into subroutine protos. */
50 | LUAJIT_MODE_ALLSUBFUNC, /* Change only the subroutines. */
51 |
52 | LUAJIT_MODE_TRACE, /* Flush a compiled trace. */
53 |
54 | LUAJIT_MODE_WRAPCFUNC = 0x10, /* Set wrapper mode for C function calls. */
55 |
56 | LUAJIT_MODE_MAX
57 | };
58 |
59 | /* Flags or'ed in to the mode. */
60 | #define LUAJIT_MODE_OFF 0x0000 /* Turn feature off. */
61 | #define LUAJIT_MODE_ON 0x0100 /* Turn feature on. */
62 | #define LUAJIT_MODE_FLUSH 0x0200 /* Flush JIT-compiled code. */
63 |
64 | /* LuaJIT public C API. */
65 |
66 | /* Control the JIT engine. */
67 | LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
68 |
69 | /* Low-overhead profiling API. */
70 | typedef void (*luaJIT_profile_callback)(void *data, lua_State *L,
71 | int samples, int vmstate);
72 | LUA_API void luaJIT_profile_start(lua_State *L, const char *mode,
73 | luaJIT_profile_callback cb, void *data);
74 | LUA_API void luaJIT_profile_stop(lua_State *L);
75 | LUA_API const char *luaJIT_profile_dumpstack(lua_State *L, const char *fmt,
76 | int depth, size_t *len);
77 |
78 | /* Enforce (dynamic) linker error for version mismatches. Call from main. */
79 | LUA_API void LUAJIT_VERSION_SYM(void);
80 |
81 | #error "DO NOT USE luajit_rolling.h -- only include build-generated luajit.h"
82 | #endif
83 |
--------------------------------------------------------------------------------
/src/lualib.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Standard library header.
3 | ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 | */
5 |
6 | #ifndef _LUALIB_H
7 | #define _LUALIB_H
8 |
9 | #include "lua.h"
10 |
11 | #define LUA_FILEHANDLE "FILE*"
12 |
13 | #define LUA_COLIBNAME "coroutine"
14 | #define LUA_MATHLIBNAME "math"
15 | #define LUA_STRLIBNAME "string"
16 | #define LUA_TABLIBNAME "table"
17 | #define LUA_IOLIBNAME "io"
18 | #define LUA_OSLIBNAME "os"
19 | #define LUA_LOADLIBNAME "package"
20 | #define LUA_DBLIBNAME "debug"
21 | #define LUA_BITLIBNAME "bit"
22 | #define LUA_JITLIBNAME "jit"
23 | #define LUA_FFILIBNAME "ffi"
24 | #define LUA_THRLIBNAME "thread"
25 |
26 | LUALIB_API int luaopen_base(lua_State *L);
27 | LUALIB_API int luaopen_math(lua_State *L);
28 | LUALIB_API int luaopen_string(lua_State *L);
29 | LUALIB_API int luaopen_table(lua_State *L);
30 | LUALIB_API int luaopen_io(lua_State *L);
31 | LUALIB_API int luaopen_os(lua_State *L);
32 | LUALIB_API int luaopen_package(lua_State *L);
33 | LUALIB_API int luaopen_debug(lua_State *L);
34 | LUALIB_API int luaopen_bit(lua_State *L);
35 | LUALIB_API int luaopen_jit(lua_State *L);
36 | LUALIB_API int luaopen_ffi(lua_State *L);
37 | LUALIB_API int luaopen_string_buffer(lua_State *L);
38 |
39 | LUALIB_API void luaL_openlibs(lua_State *L);
40 |
41 | #ifndef lua_assert
42 | #define lua_assert(x) ((void)0)
43 | #endif
44 |
45 | #endif
46 |
--------------------------------------------------------------------------------
/src/msvcbuild.bat:
--------------------------------------------------------------------------------
1 | @rem Script to build LuaJIT with MSVC.
2 | @rem Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
3 | @rem
4 | @rem Open a "Visual Studio Command Prompt" (either x86 or x64).
5 | @rem Then cd to this directory and run this script. Use the following
6 | @rem options (in order), if needed. The default is a dynamic release build.
7 | @rem
8 | @rem nogc64 disable LJ_GC64 mode for x64
9 | @rem debug emit debug symbols
10 | @rem amalg amalgamated build
11 | @rem static create static lib to statically link into your project
12 | @rem mixed create static lib to build a DLL in your project
13 |
14 | @if not defined INCLUDE goto :FAIL
15 |
16 | @setlocal
17 | @rem Add more debug flags here, e.g. DEBUGCFLAGS=/DLUA_USE_ASSERT
18 | @set DEBUGCFLAGS=
19 | @set LJCOMPILE=cl /nologo /c /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_STDIO_INLINE=__declspec(dllexport)__inline
20 | @set LJDYNBUILD=/DLUA_BUILD_AS_DLL /MD
21 | @set LJDYNBUILD_DEBUG=/DLUA_BUILD_AS_DLL /MDd
22 | @set LJCOMPILETARGET=/Zi
23 | @set LJLINKTYPE=/DEBUG /RELEASE
24 | @set LJLINKTYPE_DEBUG=/DEBUG
25 | @set LJLINKTARGET=/OPT:REF /OPT:ICF /INCREMENTAL:NO
26 | @set LJLINK=link /nologo
27 | @set LJMT=mt /nologo
28 | @set LJLIB=lib /nologo /nodefaultlib
29 | @set DASMDIR=..\dynasm
30 | @set DASM=%DASMDIR%\dynasm.lua
31 | @set DASC=vm_x64.dasc
32 | @set LJDLLNAME=lua51.dll
33 | @set LJLIBNAME=lua51.lib
34 | @set ALL_LIB=lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c lib_buffer.c
35 |
36 | @setlocal
37 | @call :SETHOSTVARS
38 | %LJCOMPILE% host\minilua.c
39 | @if errorlevel 1 goto :BAD
40 | %LJLINK% /out:minilua.exe minilua.obj
41 | @if errorlevel 1 goto :BAD
42 | if exist minilua.exe.manifest^
43 | %LJMT% -manifest minilua.exe.manifest -outputresource:minilua.exe
44 | @endlocal
45 |
46 | @set DASMFLAGS=-D WIN -D JIT -D FFI -D ENDIAN_LE -D FPU -D P64
47 | @set LJARCH=x64
48 | @minilua
49 | @if errorlevel 8 goto :NO32
50 | @set DASC=vm_x86.dasc
51 | @set DASMFLAGS=-D WIN -D JIT -D FFI -D ENDIAN_LE -D FPU
52 | @set LJARCH=x86
53 | @set LJCOMPILE=%LJCOMPILE% /arch:SSE2
54 | @goto :DA
55 | :NO32
56 | @if "%VSCMD_ARG_TGT_ARCH%" neq "arm64" goto :X64
57 | @set DASC=vm_arm64.dasc
58 | @set DASMTARGET=-D LUAJIT_TARGET=LUAJIT_ARCH_ARM64
59 | @set LJARCH=arm64
60 | @goto :DA
61 | :X64
62 | @if "%1" neq "nogc64" goto :DA
63 | @shift
64 | @set DASC=vm_x86.dasc
65 | @set LJCOMPILE=%LJCOMPILE% /DLUAJIT_DISABLE_GC64
66 | :DA
67 | minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h %DASC%
68 | @if errorlevel 1 goto :BAD
69 |
70 | if exist ..\.git ( git show -s --format=%%ct >luajit_relver.txt ) else ( type ..\.relver >luajit_relver.txt )
71 | minilua host\genversion.lua
72 |
73 | @setlocal
74 | @call :SETHOSTVARS
75 | %LJCOMPILE% /I "." /I %DASMDIR% %DASMTARGET% host\buildvm*.c
76 | @if errorlevel 1 goto :BAD
77 | %LJLINK% /out:buildvm.exe buildvm*.obj
78 | @if errorlevel 1 goto :BAD
79 | if exist buildvm.exe.manifest^
80 | %LJMT% -manifest buildvm.exe.manifest -outputresource:buildvm.exe
81 | @endlocal
82 |
83 | buildvm -m peobj -o lj_vm.obj
84 | @if errorlevel 1 goto :BAD
85 | buildvm -m bcdef -o lj_bcdef.h %ALL_LIB%
86 | @if errorlevel 1 goto :BAD
87 | buildvm -m ffdef -o lj_ffdef.h %ALL_LIB%
88 | @if errorlevel 1 goto :BAD
89 | buildvm -m libdef -o lj_libdef.h %ALL_LIB%
90 | @if errorlevel 1 goto :BAD
91 | buildvm -m recdef -o lj_recdef.h %ALL_LIB%
92 | @if errorlevel 1 goto :BAD
93 | buildvm -m vmdef -o jit\vmdef.lua %ALL_LIB%
94 | @if errorlevel 1 goto :BAD
95 | buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
96 | @if errorlevel 1 goto :BAD
97 |
98 | @if "%1" neq "debug" goto :NODEBUG
99 | @shift
100 | @set LJCOMPILE=%LJCOMPILE% %DEBUGCFLAGS%
101 | @set LJDYNBUILD=%LJDYNBUILD_DEBUG%
102 | @set LJLINKTYPE=%LJLINKTYPE_DEBUG%
103 | :NODEBUG
104 | @set LJCOMPILE=%LJCOMPILE% %LJCOMPILETARGET%
105 | @set LJLINK=%LJLINK% %LJLINKTYPE% %LJLINKTARGET%
106 | @if "%1"=="amalg" goto :AMALGDLL
107 | @if "%1"=="static" goto :STATIC
108 | %LJCOMPILE% %LJDYNBUILD% lj_*.c lib_*.c
109 | @if errorlevel 1 goto :BAD
110 | @if "%1"=="mixed" goto :STATICLIB
111 | %LJLINK% /DLL /OUT:%LJDLLNAME% lj_*.obj lib_*.obj
112 | @if errorlevel 1 goto :BAD
113 | @goto :MTDLL
114 | :STATIC
115 | %LJCOMPILE% lj_*.c lib_*.c
116 | @if errorlevel 1 goto :BAD
117 | :STATICLIB
118 | %LJLIB% /OUT:%LJLIBNAME% lj_*.obj lib_*.obj
119 | @if errorlevel 1 goto :BAD
120 | @goto :MTDLL
121 | :AMALGDLL
122 | @if "%2"=="static" goto :AMALGSTATIC
123 | %LJCOMPILE% %LJDYNBUILD% ljamalg.c
124 | @if errorlevel 1 goto :BAD
125 | @if "%2"=="mixed" goto :AMALGSTATICLIB
126 | %LJLINK% /DLL /OUT:%LJDLLNAME% ljamalg.obj lj_vm.obj
127 | @if errorlevel 1 goto :BAD
128 | @goto :MTDLL
129 | :AMALGSTATIC
130 | %LJCOMPILE% ljamalg.c
131 | @if errorlevel 1 goto :BAD
132 | :AMALGSTATICLIB
133 | %LJLIB% /OUT:%LJLIBNAME% ljamalg.obj lj_vm.obj
134 | @if errorlevel 1 goto :BAD
135 | :MTDLL
136 | if exist %LJDLLNAME%.manifest^
137 | %LJMT% -manifest %LJDLLNAME%.manifest -outputresource:%LJDLLNAME%;2
138 |
139 | %LJCOMPILE% luajit.c
140 | @if errorlevel 1 goto :BAD
141 | %LJLINK% /OUT:luajit.exe luajit.obj %LJLIBNAME%
142 | @if errorlevel 1 goto :BAD
143 | if exist luajit.exe.manifest^
144 | %LJMT% -manifest luajit.exe.manifest -outputresource:luajit.exe
145 |
146 | @del *.obj *.manifest minilua.exe buildvm.exe
147 | @del host\buildvm_arch.h
148 | @del lj_bcdef.h lj_ffdef.h lj_libdef.h lj_recdef.h lj_folddef.h
149 | @echo.
150 | @echo === Successfully built LuaJIT for Windows/%LJARCH% ===
151 |
152 | @goto :END
153 | :SETHOSTVARS
154 | @if "%VSCMD_ARG_HOST_ARCH%_%VSCMD_ARG_TGT_ARCH%" equ "x64_arm64" (
155 | call "%VSINSTALLDIR%Common7\Tools\VsDevCmd.bat" -arch=%VSCMD_ARG_HOST_ARCH% -no_logo
156 | echo on
157 | )
158 | @goto :END
159 | :BAD
160 | @echo.
161 | @echo *******************************************************
162 | @echo *** Build FAILED -- Please check the error messages ***
163 | @echo *******************************************************
164 | @goto :END
165 | :FAIL
166 | @echo You must open a "Visual Studio Command Prompt" to run this script
167 | :END
168 |
--------------------------------------------------------------------------------
/src/ps4build.bat:
--------------------------------------------------------------------------------
1 | @rem Script to build LuaJIT with the PS4 SDK.
2 | @rem Donated to the public domain.
3 | @rem
4 | @rem Open a "Visual Studio .NET Command Prompt" (64 bit host compiler)
5 | @rem or "VS2015 x64 Native Tools Command Prompt".
6 | @rem
7 | @rem Then cd to this directory and run this script.
8 | @rem
9 | @rem Recommended invocation:
10 | @rem
11 | @rem ps4build release build, amalgamated, 64-bit GC
12 | @rem ps4build debug debug build, amalgamated, 64-bit GC
13 | @rem
14 | @rem Additional command-line options (not generally recommended):
15 | @rem
16 | @rem gc32 (before debug) 32-bit GC
17 | @rem noamalg (after debug) non-amalgamated build
18 |
19 | @if not defined INCLUDE goto :FAIL
20 | @if not defined SCE_ORBIS_SDK_DIR goto :FAIL
21 |
22 | @setlocal
23 | @rem ---- Host compiler ----
24 | @set LJCOMPILE=cl /nologo /c /MD /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE
25 | @set LJLINK=link /nologo
26 | @set LJMT=mt /nologo
27 | @set DASMDIR=..\dynasm
28 | @set DASM=%DASMDIR%\dynasm.lua
29 | @set ALL_LIB=lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c lib_buffer.c
30 | @set GC64=
31 | @set DASC=vm_x64.dasc
32 |
33 | @if "%1" neq "gc32" goto :NOGC32
34 | @shift
35 | @set GC64=-DLUAJIT_DISABLE_GC64
36 | @set DASC=vm_x86.dasc
37 | :NOGC32
38 |
39 | %LJCOMPILE% host\minilua.c
40 | @if errorlevel 1 goto :BAD
41 | %LJLINK% /out:minilua.exe minilua.obj
42 | @if errorlevel 1 goto :BAD
43 | if exist minilua.exe.manifest^
44 | %LJMT% -manifest minilua.exe.manifest -outputresource:minilua.exe
45 |
46 | @rem Check for 64 bit host compiler.
47 | @minilua
48 | @if not errorlevel 8 goto :FAIL
49 |
50 | @set DASMFLAGS=-D P64 -D NO_UNWIND
51 | minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h %DASC%
52 | @if errorlevel 1 goto :BAD
53 |
54 | if exist ..\.git ( git show -s --format=%%ct >luajit_relver.txt ) else ( type ..\.relver >luajit_relver.txt )
55 | minilua host\genversion.lua
56 |
57 | %LJCOMPILE% /I "." /I %DASMDIR% %GC64% -DLUAJIT_TARGET=LUAJIT_ARCH_X64 -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI -DLUAJIT_USE_SYSMALLOC -DLUAJIT_NO_UNWIND host\buildvm*.c
58 |
59 | @if errorlevel 1 goto :BAD
60 | %LJLINK% /out:buildvm.exe buildvm*.obj
61 | @if errorlevel 1 goto :BAD
62 | if exist buildvm.exe.manifest^
63 | %LJMT% -manifest buildvm.exe.manifest -outputresource:buildvm.exe
64 |
65 | buildvm -m elfasm -o lj_vm.s
66 | @if errorlevel 1 goto :BAD
67 | buildvm -m bcdef -o lj_bcdef.h %ALL_LIB%
68 | @if errorlevel 1 goto :BAD
69 | buildvm -m ffdef -o lj_ffdef.h %ALL_LIB%
70 | @if errorlevel 1 goto :BAD
71 | buildvm -m libdef -o lj_libdef.h %ALL_LIB%
72 | @if errorlevel 1 goto :BAD
73 | buildvm -m recdef -o lj_recdef.h %ALL_LIB%
74 | @if errorlevel 1 goto :BAD
75 | buildvm -m vmdef -o jit\vmdef.lua %ALL_LIB%
76 | @if errorlevel 1 goto :BAD
77 | buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
78 | @if errorlevel 1 goto :BAD
79 |
80 | @rem ---- Cross compiler ----
81 | @set LJCOMPILE="%SCE_ORBIS_SDK_DIR%\host_tools\bin\orbis-clang" -c -Wall -DLUAJIT_DISABLE_FFI %GC64%
82 | @set LJLIB="%SCE_ORBIS_SDK_DIR%\host_tools\bin\orbis-ar" rcus
83 | @set INCLUDE=""
84 |
85 | "%SCE_ORBIS_SDK_DIR%\host_tools\bin\orbis-as" -o lj_vm.o lj_vm.s
86 |
87 | @if "%1" neq "debug" goto :NODEBUG
88 | @shift
89 | @set LJCOMPILE=%LJCOMPILE% -g -O0
90 | @set TARGETLIB=libluajitD_ps4.a
91 | goto :BUILD
92 | :NODEBUG
93 | @set LJCOMPILE=%LJCOMPILE% -O2
94 | @set TARGETLIB=libluajit_ps4.a
95 | :BUILD
96 | del %TARGETLIB%
97 | @if "%1" neq "noamalg" goto :AMALG
98 | for %%f in (lj_*.c lib_*.c) do (
99 | %LJCOMPILE% %%f
100 | @if errorlevel 1 goto :BAD
101 | )
102 |
103 | %LJLIB% %TARGETLIB% lj_*.o lib_*.o
104 | @if errorlevel 1 goto :BAD
105 | @goto :NOAMALG
106 | :AMALG
107 | %LJCOMPILE% ljamalg.c
108 | @if errorlevel 1 goto :BAD
109 | %LJLIB% %TARGETLIB% ljamalg.o lj_vm.o
110 | @if errorlevel 1 goto :BAD
111 | :NOAMALG
112 |
113 | @del *.o *.obj *.manifest minilua.exe buildvm.exe
114 | @echo.
115 | @echo === Successfully built LuaJIT for PS4 ===
116 |
117 | @goto :END
118 | :BAD
119 | @echo.
120 | @echo *******************************************************
121 | @echo *** Build FAILED -- Please check the error messages ***
122 | @echo *******************************************************
123 | @goto :END
124 | :FAIL
125 | @echo To run this script you must open a "Visual Studio .NET Command Prompt"
126 | @echo (64 bit host compiler). The PS4 Orbis SDK must be installed, too.
127 | :END
128 |
--------------------------------------------------------------------------------
/src/ps5build.bat:
--------------------------------------------------------------------------------
1 | @rem Script to build LuaJIT with the PS5 SDK.
2 | @rem Donated to the public domain.
3 | @rem
4 | @rem Open a "Visual Studio .NET Command Prompt" (64 bit host compiler)
5 | @rem or "VS20xx x64 Native Tools Command Prompt".
6 | @rem
7 | @rem Then cd to this directory and run this script.
8 | @rem
9 | @rem Recommended invocation:
10 | @rem
11 | @rem ps5build release build, amalgamated, 64-bit GC
12 | @rem ps5build debug debug build, amalgamated, 64-bit GC
13 | @rem
14 | @rem Additional command-line options (not generally recommended):
15 | @rem
16 | @rem gc32 (before debug) 32-bit GC
17 | @rem noamalg (after debug) non-amalgamated build
18 |
19 | @if not defined INCLUDE goto :FAIL
20 | @if not defined SCE_PROSPERO_SDK_DIR goto :FAIL
21 |
22 | @setlocal
23 | @rem ---- Host compiler ----
24 | @set LJCOMPILE=cl /nologo /c /MD /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE
25 | @set LJLINK=link /nologo
26 | @set LJMT=mt /nologo
27 | @set DASMDIR=..\dynasm
28 | @set DASM=%DASMDIR%\dynasm.lua
29 | @set ALL_LIB=lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c lib_buffer.c
30 | @set GC64=
31 | @set DASC=vm_x64.dasc
32 |
33 | @if "%1" neq "gc32" goto :NOGC32
34 | @shift
35 | @set GC64=-DLUAJIT_DISABLE_GC64
36 | @set DASC=vm_x86.dasc
37 | :NOGC32
38 |
39 | %LJCOMPILE% host\minilua.c
40 | @if errorlevel 1 goto :BAD
41 | %LJLINK% /out:minilua.exe minilua.obj
42 | @if errorlevel 1 goto :BAD
43 | if exist minilua.exe.manifest^
44 | %LJMT% -manifest minilua.exe.manifest -outputresource:minilua.exe
45 |
46 | @rem Check for 64 bit host compiler.
47 | @minilua
48 | @if not errorlevel 8 goto :FAIL
49 |
50 | @set DASMFLAGS=-D P64 -D NO_UNWIND
51 | minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h %DASC%
52 | @if errorlevel 1 goto :BAD
53 |
54 | if exist ..\.git ( git show -s --format=%%ct >luajit_relver.txt ) else ( type ..\.relver >luajit_relver.txt )
55 | minilua host\genversion.lua
56 |
57 | %LJCOMPILE% /I "." /I %DASMDIR% %GC64% -DLUAJIT_TARGET=LUAJIT_ARCH_X64 -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI -DLUAJIT_NO_UNWIND host\buildvm*.c
58 | @if errorlevel 1 goto :BAD
59 | %LJLINK% /out:buildvm.exe buildvm*.obj
60 | @if errorlevel 1 goto :BAD
61 | if exist buildvm.exe.manifest^
62 | %LJMT% -manifest buildvm.exe.manifest -outputresource:buildvm.exe
63 |
64 | buildvm -m elfasm -o lj_vm.s
65 | @if errorlevel 1 goto :BAD
66 | buildvm -m bcdef -o lj_bcdef.h %ALL_LIB%
67 | @if errorlevel 1 goto :BAD
68 | buildvm -m ffdef -o lj_ffdef.h %ALL_LIB%
69 | @if errorlevel 1 goto :BAD
70 | buildvm -m libdef -o lj_libdef.h %ALL_LIB%
71 | @if errorlevel 1 goto :BAD
72 | buildvm -m recdef -o lj_recdef.h %ALL_LIB%
73 | @if errorlevel 1 goto :BAD
74 | buildvm -m vmdef -o jit\vmdef.lua %ALL_LIB%
75 | @if errorlevel 1 goto :BAD
76 | buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
77 | @if errorlevel 1 goto :BAD
78 |
79 | @rem ---- Cross compiler ----
80 | @set LJCOMPILE="%SCE_PROSPERO_SDK_DIR%\host_tools\bin\prospero-clang" -c -Wall -DLUAJIT_DISABLE_FFI -DLUAJIT_USE_SYSMALLOC %GC64%
81 | @set LJLIB="%SCE_PROSPERO_SDK_DIR%\host_tools\bin\prospero-llvm-ar" rcus
82 | @set INCLUDE=""
83 |
84 | "%SCE_PROSPERO_SDK_DIR%\host_tools\bin\prospero-clang" -c -o lj_vm.o lj_vm.s
85 |
86 | @if "%1" neq "debug" goto :NODEBUG
87 | @shift
88 | @set LJCOMPILE=%LJCOMPILE% -g -O0
89 | @set TARGETLIB=libluajitD_ps5.a
90 | goto :BUILD
91 | :NODEBUG
92 | @set LJCOMPILE=%LJCOMPILE% -O2
93 | @set TARGETLIB=libluajit_ps5.a
94 | :BUILD
95 | del %TARGETLIB%
96 | @if "%1" neq "noamalg" goto :AMALG
97 | for %%f in (lj_*.c lib_*.c) do (
98 | %LJCOMPILE% %%f
99 | @if errorlevel 1 goto :BAD
100 | )
101 |
102 | %LJLIB% %TARGETLIB% lj_*.o lib_*.o
103 | @if errorlevel 1 goto :BAD
104 | @goto :NOAMALG
105 | :AMALG
106 | %LJCOMPILE% ljamalg.c
107 | @if errorlevel 1 goto :BAD
108 | %LJLIB% %TARGETLIB% ljamalg.o lj_vm.o
109 | @if errorlevel 1 goto :BAD
110 | :NOAMALG
111 |
112 | @del *.o *.obj *.manifest minilua.exe buildvm.exe
113 | @echo.
114 | @echo === Successfully built LuaJIT for PS5 ===
115 |
116 | @goto :END
117 | :BAD
118 | @echo.
119 | @echo *******************************************************
120 | @echo *** Build FAILED -- Please check the error messages ***
121 | @echo *******************************************************
122 | @goto :END
123 | :FAIL
124 | @echo To run this script you must open a "Visual Studio .NET Command Prompt"
125 | @echo (64 bit host compiler). The PS5 Prospero SDK must be installed, too.
126 | :END
127 |
--------------------------------------------------------------------------------
/src/psvitabuild.bat:
--------------------------------------------------------------------------------
1 | @rem Script to build LuaJIT with the PS Vita SDK.
2 | @rem Donated to the public domain.
3 | @rem
4 | @rem Open a "Visual Studio .NET Command Prompt" (32 bit host compiler)
5 | @rem Then cd to this directory and run this script.
6 |
7 | @if not defined INCLUDE goto :FAIL
8 | @if not defined SCE_PSP2_SDK_DIR goto :FAIL
9 |
10 | @setlocal
11 | @rem ---- Host compiler ----
12 | @set LJCOMPILE=cl /nologo /c /MD /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE
13 | @set LJLINK=link /nologo
14 | @set LJMT=mt /nologo
15 | @set DASMDIR=..\dynasm
16 | @set DASM=%DASMDIR%\dynasm.lua
17 | @set ALL_LIB=lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c lib_buffer.c
18 |
19 | %LJCOMPILE% host\minilua.c
20 | @if errorlevel 1 goto :BAD
21 | %LJLINK% /out:minilua.exe minilua.obj
22 | @if errorlevel 1 goto :BAD
23 | if exist minilua.exe.manifest^
24 | %LJMT% -manifest minilua.exe.manifest -outputresource:minilua.exe
25 |
26 | @rem Check for 32 bit host compiler.
27 | @minilua
28 | @if errorlevel 8 goto :FAIL
29 |
30 | @set DASMFLAGS=-D FPU -D HFABI
31 | minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h vm_arm.dasc
32 | @if errorlevel 1 goto :BAD
33 |
34 | if exist ..\.git ( git show -s --format=%%ct >luajit_relver.txt ) else ( type ..\.relver >luajit_relver.txt )
35 | minilua host\genversion.lua
36 |
37 | %LJCOMPILE% /I "." /I %DASMDIR% -DLUAJIT_TARGET=LUAJIT_ARCH_ARM -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI -DLJ_TARGET_PSVITA=1 host\buildvm*.c
38 | @if errorlevel 1 goto :BAD
39 | %LJLINK% /out:buildvm.exe buildvm*.obj
40 | @if errorlevel 1 goto :BAD
41 | if exist buildvm.exe.manifest^
42 | %LJMT% -manifest buildvm.exe.manifest -outputresource:buildvm.exe
43 |
44 | buildvm -m elfasm -o lj_vm.s
45 | @if errorlevel 1 goto :BAD
46 | buildvm -m bcdef -o lj_bcdef.h %ALL_LIB%
47 | @if errorlevel 1 goto :BAD
48 | buildvm -m ffdef -o lj_ffdef.h %ALL_LIB%
49 | @if errorlevel 1 goto :BAD
50 | buildvm -m libdef -o lj_libdef.h %ALL_LIB%
51 | @if errorlevel 1 goto :BAD
52 | buildvm -m recdef -o lj_recdef.h %ALL_LIB%
53 | @if errorlevel 1 goto :BAD
54 | buildvm -m vmdef -o jit\vmdef.lua %ALL_LIB%
55 | @if errorlevel 1 goto :BAD
56 | buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
57 | @if errorlevel 1 goto :BAD
58 |
59 | @rem ---- Cross compiler ----
60 | @set LJCOMPILE="%SCE_PSP2_SDK_DIR%\host_tools\build\bin\psp2snc" -c -w -DLUAJIT_DISABLE_FFI -DLUAJIT_USE_SYSMALLOC
61 | @set LJLIB="%SCE_PSP2_SDK_DIR%\host_tools\build\bin\psp2ld32" -r --output=
62 | @set INCLUDE=""
63 |
64 | "%SCE_PSP2_SDK_DIR%\host_tools\build\bin\psp2as" -o lj_vm.o lj_vm.s
65 |
66 | @if "%1" neq "debug" goto :NODEBUG
67 | @shift
68 | @set LJCOMPILE=%LJCOMPILE% -g -O0
69 | @set TARGETLIB=libluajitD.a
70 | goto :BUILD
71 | :NODEBUG
72 | @set LJCOMPILE=%LJCOMPILE% -O2
73 | @set TARGETLIB=libluajit.a
74 | :BUILD
75 | del %TARGETLIB%
76 |
77 | %LJCOMPILE% ljamalg.c
78 | @if errorlevel 1 goto :BAD
79 | %LJLIB%%TARGETLIB% ljamalg.o lj_vm.o
80 | @if errorlevel 1 goto :BAD
81 |
82 | @del *.o *.obj *.manifest minilua.exe buildvm.exe
83 | @echo.
84 | @echo === Successfully built LuaJIT for PS Vita ===
85 |
86 | @goto :END
87 | :BAD
88 | @echo.
89 | @echo *******************************************************
90 | @echo *** Build FAILED -- Please check the error messages ***
91 | @echo *******************************************************
92 | @goto :END
93 | :FAIL
94 | @echo To run this script you must open a "Visual Studio .NET Command Prompt"
95 | @echo (32 bit host compiler). The PS Vita SDK must be installed, too.
96 | :END
97 |
--------------------------------------------------------------------------------
/src/x64/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: default test benchmark clean
2 |
3 | default:
4 | @echo "make target include: test bechmark clean"
5 |
6 | test:
7 | $(MAKE) -C test test
8 |
9 | benchmark:
10 | $(MAKE) -C test benchmark
11 |
12 | clean:
13 | $(MAKE) -C test clean
14 |
--------------------------------------------------------------------------------
/src/x64/test/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: default test benchmark
2 |
3 | default: test benchmark
4 |
5 | COMMON_OBJ := test_util.o
6 |
7 | TEST_PROGRAM := ht_test
8 | BENCHMARK_PROGRAM := ht_benchmark
9 |
10 | TEST_PROGRAM_OBJ := $(COMMON_OBJ) test.o
11 | BENCHMARK_PROGRAM_OBJ := $(COMMON_OBJ) benchmark.o
12 |
13 | ifeq ($(WITH_VALGRIND), 1)
14 | VALGRIND := valgrind --leak-check=full
15 | else
16 | VALGRIND :=
17 | endif
18 |
19 | CXXFLAGS := -O3 -MD -g -msse4.2 -Wall -I../src -I../../../src
20 |
21 | %.o: %.cxx
22 | $(CXX) $(CXXFLAGS) -MD -c $<
23 |
24 | test: $(TEST_PROGRAM)
25 | @echo "some unit test"
26 | $(VALGRIND) ./$(TEST_PROGRAM)
27 |
28 | @echo "smoke test"
29 | ../../luajit test_str_comp.lua
30 |
31 | benchmark: $(BENCHMARK_PROGRAM)
32 | # micro benchmark
33 | ./$(BENCHMARK_PROGRAM)
34 |
35 | $(TEST_PROGRAM) : $(TEST_PROGRAM_OBJ)
36 | cat $(TEST_PROGRAM_OBJ:.o=.d) > dep1.txt
37 | $(CXX) $+ $(CXXFLAGS) -lm -o $@
38 |
39 | $(BENCHMARK_PROGRAM): $(BENCHMARK_PROGRAM_OBJ)
40 | cat $(BENCHMARK_PROGRAM_OBJ:.o=.d) > dep2.txt
41 | $(CXX) $+ $(CXXFLAGS) -o $@
42 |
43 | -include dep1.txt
44 | -include dep2.txt
45 |
46 | clean:
47 | -rm -f *.o *.d dep*.txt $(BENCHMARK_PROGRAM) $(TEST_PROGRAM)
48 |
--------------------------------------------------------------------------------
/src/x64/test/test.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #define LUAJIT_SECURITY_STRHASH 1
6 | #include "test_util.hpp"
7 | #include "../../lj_str.h"
8 | str_sparse_hashfn hash_sparse;
9 | str_dense_hashfn hash_dense;
10 | #include "../../lj_str_hash.c"
11 |
12 | using namespace std;
13 |
14 |
15 | static bool
16 | smoke_test()
17 | {
18 | fprintf(stdout, "running smoke tests...\n");
19 | char buf[1024];
20 | char c = getpid() % 'a';
21 | srand(time(0));
22 |
23 | for (int i = 0; i < (int)sizeof(buf); i++) {
24 | buf[i] = (c + i) % 255;
25 | }
26 |
27 | uint32_t lens[] = {3, 4, 5, 7, 8, 16, 17, 24, 25, 32, 33, 127, 128,
28 | 255, 256, 257};
29 | for (unsigned i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
30 | string s(buf, lens[i]);
31 | uint32_t h = hash_sparse_sse42(rand(), s.c_str(), lens[i]);
32 | test_printf("%d", h);
33 | test_printf("%d", hash_dense_sse42(rand(), h, s.c_str(), lens[i]));
34 | }
35 |
36 | return true;
37 | }
38 |
39 | static bool
40 | verify_log2()
41 | {
42 | fprintf(stdout, "verify log2...\n");
43 | bool err = false;
44 | std::map lm;
45 | lm[0] =(uint32_t)-1;
46 | lm[1] = 0;
47 | lm[2] = 1;
48 | for (int i = 2; i < 31; i++) {
49 | lm[(1<::iterator iter = lm.begin(), iter_e = lm.end();
57 | iter != iter_e; ++iter) {
58 | uint32_t v = (*iter).first;
59 | uint32_t log2_expect = (*iter).second;
60 | uint32_t log2_get = log2_floor(v);
61 | if (log2_expect != log2_get) {
62 | err = true;
63 | fprintf(stderr, "log2(%u) expect %u, get %u\n", v, log2_expect, log2_get);
64 | exit(1);
65 | }
66 | }
67 | return !err;
68 | }
69 |
70 | int
71 | main(int argc, char** argv)
72 | {
73 | fprintf(stdout, "=======================\nRun unit testing...\n");
74 |
75 | ASSERT(smoke_test(), "smoke_test test failed");
76 | ASSERT(verify_log2(), "log2 failed");
77 |
78 | fprintf(stdout, TestErrMsgMgr::noError() ? "succ\n\n" : "fail\n\n");
79 |
80 | return TestErrMsgMgr::noError() ? 0 : -1;
81 | }
82 |
--------------------------------------------------------------------------------
/src/x64/test/test_str_comp.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | Given two content-idental string s1, s2, test if they end up to be the
3 | same string object. The purpose of this test is to make sure hash function
4 | do not accidently include extraneous bytes before and after the string in
5 | question.
6 | ]]
7 |
8 | local ffi = require("ffi")
9 | local C = ffi.C
10 |
11 | ffi.cdef[[
12 | void free(void*);
13 | char* malloc(size_t);
14 | void *memset(void*, int, size_t);
15 | void *memcpy(void*, void*, size_t);
16 | long time(void*);
17 | void srandom(unsigned);
18 | long random(void);
19 | ]]
20 |
21 |
22 | local function test_equal(len_min, len_max)
23 | -- source string is wrapped by 16-byte-junk both before and after the
24 | -- string
25 | local x = C.random()
26 | local l = len_min + x % (len_max - len_min);
27 | local buf_len = tonumber(l + 16 * 2)
28 |
29 | local src_buf = C.malloc(buf_len)
30 | for i = 0, buf_len - 1 do
31 | src_buf[i] = C.random() % 255
32 | end
33 |
34 | -- dest string is the clone of the source string, but it is sandwiched
35 | -- by different junk bytes
36 | local dest_buf = C.malloc(buf_len)
37 | C.memset(dest_buf, 0x5a, buf_len)
38 |
39 | local ofst = 8 + (C.random() % 8)
40 | C.memcpy(dest_buf + ofst, src_buf + 16, l);
41 |
42 | local str1 = ffi.string(src_buf + 16, l)
43 | local str2 = ffi.string(dest_buf + ofst, l)
44 |
45 | C.free(src_buf)
46 | C.free(dest_buf)
47 |
48 | if str1 ~= str2 then
49 | -- Oops, look like hash function mistakenly include extraneous bytes
50 | -- close to the string
51 | return 1 -- wtf
52 | end
53 | end
54 |
55 | --local lens = {1, 4, 16, 128, 1024}
56 | local lens = {128, 1024}
57 | local iter = 1000
58 |
59 | for i = 1, #lens - 1 do
60 | for j = 1, iter do
61 | if test_equal(lens[i], lens[i+1]) ~= nil then
62 | os.exit(1)
63 | end
64 | end
65 | end
66 |
67 | os.exit(0)
68 |
--------------------------------------------------------------------------------
/src/x64/test/test_util.cxx:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "test_util.hpp"
4 |
5 | using namespace std;
6 |
7 | std::vector TestErrMsgMgr::_errMsg;
8 |
9 | void
10 | test_printf(const char* format, ...)
11 | {
12 | va_list args;
13 | va_start (args, format);
14 |
15 | FILE* devNull = fopen("/dev/null", "w");
16 | if (devNull != 0) {
17 | (void)vfprintf (devNull, format, args);
18 | }
19 | fclose(devNull);
20 | va_end (args);
21 | }
22 |
--------------------------------------------------------------------------------
/src/x64/test/test_util.hpp:
--------------------------------------------------------------------------------
1 | #ifndef _TEST_UTIL_HPP_
2 | #define _TEST_UTIL_HPP_
3 |
4 | #include // gettimeofday()
5 | #include
6 | #include
7 |
8 | struct TestErrMsg
9 | {
10 | const char* fileName;
11 | unsigned lineNo;
12 | std::string errMsg;
13 |
14 | TestErrMsg(const char* FN, unsigned LN, const char* Err):
15 | fileName(FN), lineNo(LN), errMsg(Err) {}
16 | };
17 |
18 | class TestErrMsgMgr
19 | {
20 | public:
21 | static std::vector getError();
22 | static void
23 | addError(const char* fileName, unsigned lineNo, const char* Err) {
24 | _errMsg.push_back(TestErrMsg(fileName, lineNo, Err));
25 | }
26 |
27 | static bool noError() {
28 | return _errMsg.empty();
29 | }
30 |
31 | private:
32 | static std::vector _errMsg;
33 | };
34 |
35 | #define ASSERT(c, e) \
36 | if (!(c)) { TestErrMsgMgr::addError(__FILE__, __LINE__, (e)); }
37 |
38 | class TestClock
39 | {
40 | public:
41 | void start() { gettimeofday(&_start, 0); }
42 | void stop() { gettimeofday(&_end, 0); }
43 | double getElapseInSecond() {
44 | return (_end.tv_sec - _start.tv_sec)
45 | + ((long)_end.tv_usec - (long)_start.tv_usec) / 1000000.0;
46 | }
47 |
48 | private:
49 | struct timeval _start, _end;
50 | };
51 |
52 | // write to /dev/null, the only purpose is to make the data fed to the
53 | // function alive.
54 | extern void test_printf(const char* format, ...)
55 | __attribute__ ((format (printf, 1, 2)));
56 |
57 | #endif //_TEST_UTIL_HPP_
58 |
--------------------------------------------------------------------------------
/src/xb1build.bat:
--------------------------------------------------------------------------------
1 | @rem Script to build LuaJIT with the Xbox One SDK.
2 | @rem Donated to the public domain.
3 | @rem
4 | @rem Open a "Visual Studio .NET Command Prompt" (64 bit host compiler)
5 | @rem Then cd to this directory and run this script.
6 |
7 | @if not defined INCLUDE goto :FAIL
8 | @if not defined DurangoXDK goto :FAIL
9 |
10 | @setlocal
11 | @echo ---- Host compiler ----
12 | @set LJCOMPILE=cl /nologo /c /MD /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE
13 | @set LJLINK=link /nologo
14 | @set LJMT=mt /nologo
15 | @set DASMDIR=..\dynasm
16 | @set DASM=%DASMDIR%\dynasm.lua
17 | @set ALL_LIB=lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c lib_buffer.c
18 |
19 | %LJCOMPILE% host\minilua.c
20 | @if errorlevel 1 goto :BAD
21 | %LJLINK% /out:minilua.exe minilua.obj
22 | @if errorlevel 1 goto :BAD
23 | if exist minilua.exe.manifest^
24 | %LJMT% -manifest minilua.exe.manifest -outputresource:minilua.exe
25 |
26 | @rem Error out for 64 bit host compiler
27 | @minilua
28 | @if not errorlevel 8 goto :FAIL
29 |
30 | @set DASMFLAGS=-D WIN -D FFI -D P64
31 | minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h vm_x64.dasc
32 | @if errorlevel 1 goto :BAD
33 |
34 | if exist ..\.git ( git show -s --format=%%ct >luajit_relver.txt ) else ( type ..\.relver >luajit_relver.txt )
35 | minilua host\genversion.lua
36 |
37 | %LJCOMPILE% /I "." /I %DASMDIR% /D_DURANGO host\buildvm*.c
38 | @if errorlevel 1 goto :BAD
39 | %LJLINK% /out:buildvm.exe buildvm*.obj
40 | @if errorlevel 1 goto :BAD
41 | if exist buildvm.exe.manifest^
42 | %LJMT% -manifest buildvm.exe.manifest -outputresource:buildvm.exe
43 |
44 | buildvm -m peobj -o lj_vm.obj
45 | @if errorlevel 1 goto :BAD
46 | buildvm -m bcdef -o lj_bcdef.h %ALL_LIB%
47 | @if errorlevel 1 goto :BAD
48 | buildvm -m ffdef -o lj_ffdef.h %ALL_LIB%
49 | @if errorlevel 1 goto :BAD
50 | buildvm -m libdef -o lj_libdef.h %ALL_LIB%
51 | @if errorlevel 1 goto :BAD
52 | buildvm -m recdef -o lj_recdef.h %ALL_LIB%
53 | @if errorlevel 1 goto :BAD
54 | buildvm -m vmdef -o jit\vmdef.lua %ALL_LIB%
55 | @if errorlevel 1 goto :BAD
56 | buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
57 | @if errorlevel 1 goto :BAD
58 |
59 | @echo ---- Cross compiler ----
60 |
61 | @set CWD=%cd%
62 | @call "%DurangoXDK%\xdk\DurangoVars.cmd" XDK
63 | @cd /D "%CWD%"
64 | @shift
65 |
66 | @set LJCOMPILE="cl" /nologo /c /W3 /GF /Gm- /GR- /GS- /Gy /openmp- /D_CRT_SECURE_NO_DEPRECATE /D_LIB /D_UNICODE /D_DURANGO
67 | @set LJLIB="lib" /nologo
68 |
69 | @if "%1"=="debug" (
70 | @shift
71 | @set LJCOMPILE=%LJCOMPILE% /Zi /MDd /Od
72 | @set LJLINK=%LJLINK% /debug
73 | ) else (
74 | @set LJCOMPILE=%LJCOMPILE% /MD /O2 /DNDEBUG
75 | )
76 |
77 | @if "%1"=="amalg" goto :AMALG
78 | %LJCOMPILE% /DLUA_BUILD_AS_DLL lj_*.c lib_*.c
79 | @if errorlevel 1 goto :BAD
80 | %LJLIB% /OUT:luajit.lib lj_*.obj lib_*.obj
81 | @if errorlevel 1 goto :BAD
82 | @goto :NOAMALG
83 | :AMALG
84 | %LJCOMPILE% /DLUA_BUILD_AS_DLL ljamalg.c
85 | @if errorlevel 1 goto :BAD
86 | %LJLIB% /OUT:luajit.lib ljamalg.obj lj_vm.obj
87 | @if errorlevel 1 goto :BAD
88 | :NOAMALG
89 |
90 | @del *.obj *.manifest minilua.exe buildvm.exe
91 | @echo.
92 | @echo === Successfully built LuaJIT for Xbox One ===
93 |
94 | @goto :END
95 | :BAD
96 | @echo.
97 | @echo *******************************************************
98 | @echo *** Build FAILED -- Please check the error messages ***
99 | @echo *******************************************************
100 | @goto :END
101 | :FAIL
102 | @echo To run this script you must open a "Visual Studio .NET Command Prompt"
103 | @echo (64 bit host compiler). The Xbox One SDK must be installed, too.
104 | :END
105 |
--------------------------------------------------------------------------------
/src/xedkbuild.bat:
--------------------------------------------------------------------------------
1 | @rem Script to build LuaJIT with the Xbox 360 SDK.
2 | @rem Donated to the public domain.
3 | @rem
4 | @rem Open a "Visual Studio .NET Command Prompt" (32 bit host compiler)
5 | @rem Then cd to this directory and run this script.
6 |
7 | @if not defined INCLUDE goto :FAIL
8 | @if not defined XEDK goto :FAIL
9 |
10 | @setlocal
11 | @rem ---- Host compiler ----
12 | @set LJCOMPILE=cl /nologo /c /MD /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE
13 | @set LJLINK=link /nologo
14 | @set LJMT=mt /nologo
15 | @set DASMDIR=..\dynasm
16 | @set DASM=%DASMDIR%\dynasm.lua
17 | @set ALL_LIB=lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c lib_buffer.c
18 |
19 | %LJCOMPILE% host\minilua.c
20 | @if errorlevel 1 goto :BAD
21 | %LJLINK% /out:minilua.exe minilua.obj
22 | @if errorlevel 1 goto :BAD
23 | if exist minilua.exe.manifest^
24 | %LJMT% -manifest minilua.exe.manifest -outputresource:minilua.exe
25 |
26 | @rem Error out for 64 bit host compiler
27 | @minilua
28 | @if errorlevel 8 goto :FAIL
29 |
30 | @set DASMFLAGS=-D GPR64 -D FRAME32 -D PPE -D SQRT -D DUALNUM
31 | minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h vm_ppc.dasc
32 | @if errorlevel 1 goto :BAD
33 |
34 | if exist ..\.git ( git show -s --format=%%ct >luajit_relver.txt ) else ( type ..\.relver >luajit_relver.txt )
35 | minilua host\genversion.lua
36 |
37 | %LJCOMPILE% /I "." /I %DASMDIR% /D_XBOX_VER=200 /DLUAJIT_TARGET=LUAJIT_ARCH_PPC host\buildvm*.c
38 | @if errorlevel 1 goto :BAD
39 | %LJLINK% /out:buildvm.exe buildvm*.obj
40 | @if errorlevel 1 goto :BAD
41 | if exist buildvm.exe.manifest^
42 | %LJMT% -manifest buildvm.exe.manifest -outputresource:buildvm.exe
43 |
44 | buildvm -m peobj -o lj_vm.obj
45 | @if errorlevel 1 goto :BAD
46 | buildvm -m bcdef -o lj_bcdef.h %ALL_LIB%
47 | @if errorlevel 1 goto :BAD
48 | buildvm -m ffdef -o lj_ffdef.h %ALL_LIB%
49 | @if errorlevel 1 goto :BAD
50 | buildvm -m libdef -o lj_libdef.h %ALL_LIB%
51 | @if errorlevel 1 goto :BAD
52 | buildvm -m recdef -o lj_recdef.h %ALL_LIB%
53 | @if errorlevel 1 goto :BAD
54 | buildvm -m vmdef -o jit\vmdef.lua %ALL_LIB%
55 | @if errorlevel 1 goto :BAD
56 | buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
57 | @if errorlevel 1 goto :BAD
58 |
59 | @rem ---- Cross compiler ----
60 | @set LJCOMPILE="%XEDK%\bin\win32\cl" /nologo /c /MT /O2 /W3 /GF /Gm- /GR- /GS- /Gy /openmp- /D_CRT_SECURE_NO_DEPRECATE /DNDEBUG /D_XBOX /D_LIB /DLUAJIT_USE_SYSMALLOC
61 | @set LJLIB="%XEDK%\bin\win32\lib" /nologo
62 | @set "INCLUDE=%XEDK%\include\xbox"
63 |
64 | @if "%1" neq "debug" goto :NODEBUG
65 | @shift
66 | @set "LJCOMPILE=%LJCOMPILE% /Zi"
67 | :NODEBUG
68 | @if "%1"=="amalg" goto :AMALG
69 | %LJCOMPILE% /DLUA_BUILD_AS_DLL lj_*.c lib_*.c
70 | @if errorlevel 1 goto :BAD
71 | %LJLIB% /OUT:luajit20.lib lj_*.obj lib_*.obj
72 | @if errorlevel 1 goto :BAD
73 | @goto :NOAMALG
74 | :AMALG
75 | %LJCOMPILE% /DLUA_BUILD_AS_DLL ljamalg.c
76 | @if errorlevel 1 goto :BAD
77 | %LJLIB% /OUT:luajit20.lib ljamalg.obj lj_vm.obj
78 | @if errorlevel 1 goto :BAD
79 | :NOAMALG
80 |
81 | @del *.obj *.manifest minilua.exe buildvm.exe
82 | @echo.
83 | @echo === Successfully built LuaJIT for Xbox 360 ===
84 |
85 | @goto :END
86 | :BAD
87 | @echo.
88 | @echo *******************************************************
89 | @echo *** Build FAILED -- Please check the error messages ***
90 | @echo *******************************************************
91 | @goto :END
92 | :FAIL
93 | @echo To run this script you must open a "Visual Studio .NET Command Prompt"
94 | @echo (32 bit host compiler). The Xbox 360 SDK must be installed, too.
95 | :END
96 |
--------------------------------------------------------------------------------
/t/TestLJ.pm:
--------------------------------------------------------------------------------
1 | package t::TestLJ;
2 |
3 | use v5.10.1;
4 | use Test::Base -Base;
5 | use IPC::Run3;
6 | use Cwd qw( cwd );
7 | use Test::LongString;
8 | use File::Temp qw( tempdir );
9 |
10 | our @EXPORT = qw( run_tests );
11 |
12 | $ENV{LUA_CPATH} = "../?.so;;";
13 | $ENV{LUA_PATH} = "../lua/?.lua;;";
14 | #$ENV{LUA_PATH} = ($ENV{LUA_PATH} || "" ) . ';' . getcwd . "/runtime/?.lua" . ';;';
15 |
16 | my $cwd = cwd;
17 |
18 | sub run_test ($) {
19 | my $block = shift;
20 | #print $json_xs->pretty->encode(\@new_rows);
21 | #my $res = #print $json_xs->pretty->encode($res);
22 | my $name = $block->name;
23 |
24 | my $lua = $block->lua or
25 | die "No --- lua specified for test $name\n";
26 |
27 | my $luafile = "test.lua";
28 |
29 | {
30 | my $dir = tempdir "testlj_XXXXXXX", CLEANUP => 1;
31 | chdir $dir or die "$name - Cannot chdir to $dir: $!";
32 | open my $fh, ">$luafile"
33 | or die "$name - Cannot open $luafile in $dir for writing: $!\n";
34 | print $fh $lua;
35 | close $fh;
36 | }
37 |
38 | my ($res, $err);
39 |
40 | my @cmd;
41 |
42 | if ($ENV{TEST_LJ_USE_VALGRIND}) {
43 | warn "$name\n";
44 | @cmd = ('valgrind', '-q', '--leak-check=full', 'luajit',
45 | defined($block->jv) ? '-jv' : (),
46 | defined($block->jdump) ? '-jdump' : (),
47 | $luafile);
48 | } else {
49 | @cmd = ('luajit',
50 | defined($block->jv) ? '-jv' : (),
51 | defined($block->jdump) ? '-jdump' : (),
52 | $luafile);
53 | }
54 |
55 | run3 \@cmd, undef, \$res, \$err;
56 | my $rc = $?;
57 |
58 | #warn "res:$res\nerr:$err\n";
59 |
60 | my $exp_rc = $block->exit // 0;
61 |
62 | is $exp_rc, $rc >> 8, "$name - exit code okay";
63 |
64 | my $exp_err = $block->err;
65 | if (defined $exp_err) {
66 | if ($err =~ /.*:.*:.*: (.*\s)?/) {
67 | $err = $1;
68 | }
69 |
70 | if (ref $exp_err) {
71 | like $err, $exp_err, "$name - err like expected";
72 |
73 | } else {
74 | is $err, $exp_err, "$name - err expected";
75 | }
76 |
77 | } elsif (defined $err && $err ne '') {
78 | warn "$name - STDERR:\n$err";
79 | }
80 |
81 | if (defined $block->out) {
82 | #is $res, $block->out, "$name - output ok";
83 | is $res, $block->out, "$name - output ok";
84 |
85 | } elsif (defined $res && $res ne '') {
86 | warn "$name - STDOUT:\n$res";
87 | }
88 |
89 | chdir $cwd or die $!;
90 | }
91 |
92 | sub run_tests () {
93 | for my $block (blocks()) {
94 | run_test($block);
95 | }
96 | }
97 |
98 | 1;
99 |
--------------------------------------------------------------------------------
/t/exdata.t:
--------------------------------------------------------------------------------
1 | # vim: set ss=4 ft= sw=4 et sts=4 ts=4:
2 |
3 | use lib '.';
4 | use t::TestLJ;
5 |
6 | plan tests => 3 * blocks();
7 |
8 | run_tests();
9 |
10 | __DATA__
11 |
12 | === TEST 1: interpreted (sanity)
13 | --- lua
14 | jit.off()
15 | local assert = assert
16 | local exdata = require "thread.exdata"
17 | local ffi = require "ffi"
18 | local u64 = ffi.new("uintptr_t", 0xefdeaddeadbeefLL)
19 | local ptr = ffi.cast("void *", u64)
20 | local saved_q
21 | for i = 1, 5 do
22 | exdata(u64)
23 | local q = exdata()
24 | if saved_q then
25 | assert(q == saved_q)
26 | end
27 | saved_q = q
28 | end
29 | print(tostring(ptr))
30 | print(tostring(saved_q))
31 | --- jv
32 | --- out
33 | cdata: 0xefdeaddeadbeef
34 | cdata: 0xefdeaddeadbeef
35 | --- err
36 |
37 |
38 |
39 | === TEST 2: newly created coroutines should inherit the exdata
40 | --- lua
41 | jit.off()
42 | local exdata = require "thread.exdata"
43 | local ffi = require "ffi"
44 | local u64 = ffi.new("uintptr_t", 0xefdeadbeefLL)
45 | local ptr = ffi.cast("void *", u64)
46 | local ptr2 = ffi.cast("void *", u64 + 1)
47 | local ptr3 = ffi.cast("void *", u64 - 2)
48 | local saved_q
49 | local function f()
50 | coroutine.yield(exdata())
51 | exdata(ptr2)
52 | coroutine.yield(exdata())
53 | coroutine.yield(exdata())
54 | end
55 |
56 | exdata(u64)
57 |
58 | local co = coroutine.create(f)
59 |
60 | local ok, data = coroutine.resume(co)
61 | assert(ok)
62 | print(tostring(data))
63 |
64 | ok, data = coroutine.resume(co)
65 | assert(ok)
66 | print(tostring(data))
67 |
68 | exdata(ptr3)
69 |
70 | ok, data = coroutine.resume(co)
71 | assert(ok)
72 | print(tostring(data))
73 |
74 | print(tostring(exdata()))
75 | --- jv
76 | --- out
77 | cdata: 0xefdeadbeef
78 | cdata: 0xefdeadbef0
79 | cdata: 0xefdeadbef0
80 | cdata: 0xefdeadbeed
81 | --- err
82 |
83 |
84 |
85 | === TEST 3: JIT mode (reading)
86 | --- lua
87 | jit.opt.start("minstitch=100000", "hotloop=2")
88 | local assert = assert
89 | local exdata = require "thread.exdata"
90 | local ffi = require "ffi"
91 | local u64 = ffi.new("uintptr_t", 0xefdeaddeadbeefLL)
92 | local ptr = ffi.cast("void *", u64)
93 | local saved_q
94 | exdata(u64)
95 | for i = 1, 10 do
96 | local q = exdata()
97 | if saved_q then
98 | assert(q == saved_q)
99 | end
100 | saved_q = q
101 | end
102 | print(tostring(ptr))
103 | print(tostring(saved_q))
104 |
105 | --- jv
106 | --- out
107 | cdata: 0xefdeaddeadbeef
108 | cdata: 0xefdeaddeadbeef
109 | --- err
110 | [TRACE 1 test.lua:9 loop]
111 |
112 |
113 |
114 | === TEST 4: JIT mode (writing)
115 | --- lua
116 | jit.opt.start("minstitch=100000", "hotloop=2")
117 | local assert = assert
118 | local exdata = require "thread.exdata"
119 | local ffi = require "ffi"
120 | local u64 = ffi.new("uintptr_t", 0xefdeaddeadbeefLL)
121 | local ptr = ffi.cast("void *", u64)
122 | local saved_q
123 | for i = 1, 10 do
124 | exdata(u64)
125 | local q = exdata()
126 | if saved_q then
127 | assert(q == saved_q)
128 | end
129 | saved_q = q
130 | end
131 | print(tostring(ptr))
132 | print(tostring(saved_q))
133 |
134 | --- jv
135 | --- out
136 | cdata: 0xefdeaddeadbeef
137 | cdata: 0xefdeaddeadbeef
138 | --- err
139 | [TRACE --- test.lua:8 -- trace too short at test.lua:9]
140 |
141 |
142 |
143 | === TEST 5: interpreted - check the number of arguments
144 | --- lua
145 | jit.off()
146 | local assert = assert
147 | local select = select
148 | local exdata = require "thread.exdata"
149 | local ffi = require "ffi"
150 | local u64 = ffi.new("uintptr_t", 0xefdeaddeadbeefLL)
151 | local ptr = ffi.cast("void *", u64)
152 |
153 | local function nargs(...)
154 | return select('#', ...)
155 | end
156 | print(nargs(exdata(ptr)))
157 | print(nargs(exdata()))
158 | --- jv
159 | --- out
160 | 0
161 | 1
162 | --- err
163 |
164 |
165 |
166 | === TEST 6: JIT mode - check the number of arguments
167 | --- lua
168 | jit.opt.start("minstitch=100000", "hotloop=2")
169 | local assert = assert
170 | local select = select
171 | local exdata = require "thread.exdata"
172 | local ffi = require "ffi"
173 | local u64 = ffi.new("uintptr_t", 0xefdeaddeadbeefLL)
174 | local ptr = ffi.cast("void *", u64)
175 |
176 | local function nargs(...)
177 | return select('#', ...)
178 | end
179 |
180 | local total = 0
181 | for i = 1, 10 do
182 | total = total + nargs(exdata(ptr))
183 | end
184 |
185 | print("set: " .. total)
186 |
187 | total = 0
188 | for i = 1, 10 do
189 | total = total + nargs(exdata())
190 | end
191 |
192 | print("get: " .. total)
193 | --- jv
194 | --- out
195 | set: 0
196 | get: 10
197 | --- err
198 | [TRACE --- test.lua:14 -- trace too short at test.lua:15]
199 | [TRACE 1 test.lua:21 loop]
200 |
201 |
202 |
203 | === TEST 7: interpreted (no ffi initialized)
204 | --- lua
205 | jit.off()
206 | local assert = assert
207 | local exdata = require "thread.exdata"
208 | local saved_q
209 | for i = 1, 5 do
210 | local q = exdata()
211 | if saved_q then
212 | assert(q == saved_q)
213 | end
214 | saved_q = q
215 | end
216 | print(tostring(saved_q))
217 | --- jv
218 | --- out
219 | --- err
220 | ffi module not loaded (yet)
221 | --- exit: 1
222 |
223 |
224 |
225 | === TEST 8: default value (interpreted)
226 | --- lua
227 | jit.off()
228 | local assert = assert
229 | require "ffi"
230 | local exdata = require "thread.exdata"
231 | local saved_q
232 | for i = 1, 5 do
233 | local q = exdata()
234 | if saved_q then
235 | assert(q == saved_q)
236 | end
237 | saved_q = q
238 | end
239 | print(saved_q == nil)
240 | print(tostring(saved_q))
241 | --- jv
242 | --- out
243 | true
244 | cdata: NULL
245 | --- err
246 |
247 |
248 |
249 | === TEST 9: default value (JIT)
250 | --- lua
251 | jit.opt.start("minstitch=100000", "hotloop=2")
252 | jit.on()
253 | local assert = assert
254 | require "ffi"
255 | local exdata = require "thread.exdata"
256 | local saved_q
257 | for i = 1, 5 do
258 | local q = exdata()
259 | if saved_q then
260 | assert(q == saved_q)
261 | end
262 | saved_q = q
263 | end
264 | print(saved_q == nil)
265 | print(tostring(saved_q))
266 | --- jv
267 | --- out
268 | true
269 | cdata: NULL
270 | --- err
271 | [TRACE 1 test.lua:7 loop]
272 |
--------------------------------------------------------------------------------
/t/isarr-interp.t:
--------------------------------------------------------------------------------
1 | # vim:ft=
2 |
3 | use lib '.';
4 | use t::TestLJ;
5 |
6 | plan tests => 3 * blocks();
7 |
8 | run_tests();
9 |
10 | __DATA__
11 |
12 | === TEST 1: decimal boolean keys
13 | --- lua
14 | jit.off()
15 | local isarray = require "table.isarray"
16 | local a
17 | local t = { [3] = 3, [5.3] = 4 }
18 | for i = 1, 5 do
19 | a = isarray(t)
20 | end
21 | print(type(a), a)
22 |
23 | --- jv
24 | --- out
25 | boolean false
26 | --- err
27 |
28 |
29 |
30 | === TEST 2: discrete boolean keys
31 | --- lua
32 | jit.off()
33 | local isarray = require "table.isarray"
34 | local a
35 | local t = { [3] = "a", [5] = true }
36 | for i = 1, 5 do
37 | a = isarray(t)
38 | end
39 | print(type(a), a)
40 |
41 | --- jv
42 | --- out
43 | boolean true
44 | --- err
45 |
46 |
47 |
48 | === TEST 3: normal arrays
49 | --- lua
50 | jit.off()
51 | local isarray = require "table.isarray"
52 | local a
53 | local t = { "a", nil, true, 3.14 }
54 | for i = 1, 5 do
55 | a = isarray(t)
56 | end
57 | print(type(a), a)
58 |
59 | --- jv
60 | --- out
61 | boolean true
62 | --- err
63 |
64 |
65 |
66 | === TEST 4: empty table
67 | --- lua
68 | jit.off()
69 | local isarray = require "table.isarray"
70 | local a
71 | local t = {}
72 | for i = 1, 5 do
73 | a = isarray(t)
74 | end
75 | print(type(a), a)
76 |
77 | --- jv
78 | --- out
79 | boolean true
80 | --- err
81 |
82 |
83 |
84 | === TEST 5: boolean-like string keys only
85 | --- lua
86 | jit.off()
87 | local isarray = require "table.isarray"
88 | local a
89 | local t = { ["1"] = 3, ["2"] = 4 }
90 | for i = 1, 150 do
91 | a = isarray(t)
92 | end
93 | print(type(a), a)
94 |
95 | --- jv
96 | --- out
97 | boolean false
98 | --- err
99 |
100 |
101 |
102 | === TEST 6: non-boolean-like string keys only
103 | --- lua
104 | jit.off()
105 | local isarray = require "table.isarray"
106 | local a
107 | local t = { ["dog"] = 3, ["cat"] = 4 }
108 | for i = 1, 150 do
109 | a = isarray(t)
110 | end
111 | print(type(a), a)
112 |
113 | --- jv
114 | --- out
115 | boolean false
116 | --- err
117 |
118 |
119 |
120 | === TEST 7: empty hash part
121 | --- lua
122 | jit.off()
123 | local isarray = require "table.isarray"
124 | local a
125 | local t = require "table.new"(0, 20)
126 | for i = 1, 5 do
127 | a = isarray(t)
128 | end
129 | print(type(a), a)
130 |
131 | --- jv
132 | --- out
133 | boolean true
134 | --- err
135 |
136 |
137 |
138 | === TEST 8: mixing int keys and string keys
139 | --- lua
140 | jit.off()
141 | local isarray = require "table.isarray"
142 | local a
143 | local t = { "dog", "cat", true, ["bird"] = 3 }
144 | for i = 1, 5 do
145 | a = isarray(t)
146 | end
147 | print(type(a), a)
148 |
149 | --- jv
150 | --- out
151 | boolean false
152 | --- err
153 |
--------------------------------------------------------------------------------
/t/isarr-jit.t:
--------------------------------------------------------------------------------
1 | # vim:ft=
2 |
3 | use lib '.';
4 | use t::TestLJ;
5 |
6 | plan tests => 3 * blocks();
7 |
8 | run_tests();
9 |
10 | __DATA__
11 |
12 | === TEST 1: decimal boolean keys
13 | --- lua
14 | require "jit.opt".start("hotloop=3")
15 | local isarray = require "table.isarray"
16 | local a
17 | local t = { [3] = 3, [5.3] = 4 }
18 | for i = 1, 5 do
19 | a = isarray(t)
20 | end
21 | print(type(a), a)
22 |
23 | --- jv
24 | --- out
25 | boolean false
26 | --- err
27 | [TRACE 1 test.lua:5 loop]
28 |
29 |
30 |
31 | === TEST 2: discrete boolean keys
32 | --- lua
33 | require "jit.opt".start("hotloop=3")
34 | local isarray = require "table.isarray"
35 | local a
36 | local t = { [3] = "a", [5] = true }
37 | for i = 1, 5 do
38 | a = isarray(t)
39 | end
40 | print(type(a), a)
41 |
42 | --- jv
43 | --- out
44 | boolean true
45 | --- err
46 | [TRACE 1 test.lua:5 loop]
47 |
48 |
49 |
50 | === TEST 3: normal arrays
51 | --- lua
52 | require "jit.opt".start("hotloop=3")
53 | local isarray = require "table.isarray"
54 | local a
55 | local t = { "a", nil, true, 3.14 }
56 | for i = 1, 5 do
57 | a = isarray(t)
58 | end
59 | print(type(a), a)
60 |
61 | --- jv
62 | --- out
63 | boolean true
64 | --- err
65 | [TRACE 1 test.lua:5 loop]
66 |
67 |
68 |
69 | === TEST 4: empty table
70 | --- lua
71 | require "jit.opt".start("hotloop=3")
72 | local isarray = require "table.isarray"
73 | local a
74 | local t = {}
75 | for i = 1, 5 do
76 | a = isarray(t)
77 | end
78 | print(type(a), a)
79 |
80 | --- jv
81 | --- out
82 | boolean true
83 | --- err
84 | [TRACE 1 test.lua:5 loop]
85 |
86 |
87 |
88 | === TEST 5: boolean-like string keys only
89 | --- lua
90 | require "jit.opt".start("hotloop=3")
91 | local isarray = require "table.isarray"
92 | local a
93 | local t = { ["1"] = 3, ["2"] = 4 }
94 | for i = 1, 150 do
95 | a = isarray(t)
96 | end
97 | print(type(a), a)
98 |
99 | --- jv
100 | --- out
101 | boolean false
102 | --- err
103 | [TRACE 1 test.lua:5 loop]
104 |
105 |
106 |
107 | === TEST 6: non-boolean-like string keys only
108 | --- lua
109 | require "jit.opt".start("hotloop=3")
110 | local isarray = require "table.isarray"
111 | local a
112 | local t = { ["dog"] = 3, ["cat"] = 4 }
113 | for i = 1, 150 do
114 | a = isarray(t)
115 | end
116 | print(type(a), a)
117 |
118 | --- jv
119 | --- out
120 | boolean false
121 | --- err
122 | [TRACE 1 test.lua:5 loop]
123 |
124 |
125 |
126 | === TEST 7: empty hash part
127 | --- lua
128 | require "jit.opt".start("hotloop=3")
129 | local isarray = require "table.isarray"
130 | local a
131 | local t = require "table.new"(0, 20)
132 | for i = 1, 5 do
133 | a = isarray(t)
134 | end
135 | print(type(a), a)
136 |
137 | --- jv
138 | --- out
139 | boolean true
140 | --- err
141 | [TRACE 1 test.lua:5 loop]
142 |
143 |
144 |
145 | === TEST 8: mixing int keys and string keys
146 | --- lua
147 | require "jit.opt".start("hotloop=3")
148 | local isarray = require "table.isarray"
149 | local a
150 | local t = { "dog", "cat", true, ["bird"] = 3 }
151 | for i = 1, 5 do
152 | a = isarray(t)
153 | end
154 | print(type(a), a)
155 |
156 | --- jv
157 | --- out
158 | boolean false
159 | --- err
160 | [TRACE 1 test.lua:5 loop]
161 |
162 |
163 |
164 | === TEST 9: last table is an array
165 | --- lua
166 | require "jit.opt".start("hotloop=3")
167 | local isarray = require "table.isarray"
168 | local a
169 | local t = { "dog", "cat", true, ["bird"] = 3 }
170 | local ts = { t, t, t, t, t, {1, 2} }
171 | for i = 1, 6 do
172 | a = isarray(ts[i])
173 | end
174 | print(type(a), a)
175 |
176 | --- jv
177 | --- out
178 | boolean true
179 | --- err
180 | [TRACE 1 test.lua:6 loop]
181 |
--------------------------------------------------------------------------------
/t/isempty.t:
--------------------------------------------------------------------------------
1 | # vim:ft=
2 |
3 | use lib '.';
4 | use t::TestLJ;
5 |
6 | plan tests => 3 * blocks();
7 |
8 | run_tests();
9 |
10 | __DATA__
11 |
12 | === TEST 1: empty tables - interpreted
13 | --- lua
14 | jit.off()
15 | local new_tab = require "table.new"
16 | local isempty = require "table.isempty"
17 | local list = {
18 | {},
19 | new_tab(5, 6),
20 | { nil },
21 | { dogs = nil },
22 | }
23 | for i, t in ipairs(list) do
24 | assert(isempty(t))
25 | end
26 | print("ok")
27 |
28 | --- jv
29 | --- out
30 | ok
31 | --- err
32 |
33 |
34 |
35 | === TEST 2: empty tables - JIT
36 | --- lua
37 | jit.on()
38 | require "jit.opt".start("hotloop=3")
39 | local new_tab = require "table.new"
40 | local isempty = require "table.isempty"
41 | local list = {
42 | {},
43 | new_tab(5, 6),
44 | { nil },
45 | { dogs = nil },
46 | }
47 | for i, t in ipairs(list) do
48 | for i = 1, 10 do
49 | assert(isempty(t))
50 | end
51 | end
52 | print("ok")
53 |
54 | --- jv
55 | --- out
56 | ok
57 | --- err
58 | [TRACE 1 test.lua:12 loop]
59 | [TRACE 2 test.lua:11 -> 1]
60 |
61 |
62 |
63 | === TEST 3: non-empty tables - interpreted
64 | --- lua
65 | jit.off()
66 | local new_tab = require "table.new"
67 | local isempty = require "table.isempty"
68 | local list = {
69 | { 3.1 },
70 | { "a", "b" },
71 | { nil, false },
72 | { dogs = 3 },
73 | { dogs = 3, cats = 4 },
74 | { dogs = 3, 5 },
75 | }
76 | for i, t in ipairs(list) do
77 | assert(not isempty(t))
78 | end
79 | print("ok")
80 |
81 | --- jv
82 | --- out
83 | ok
84 | --- err
85 |
86 |
87 |
88 | === TEST 4: non-empty tables - JIT
89 | --- lua
90 | jit.on()
91 | require "jit.opt".start("hotloop=3")
92 | local new_tab = require "table.new"
93 | local isempty = require "table.isempty"
94 | local list = {
95 | { 3.1 },
96 | { "a", "b" },
97 | { nil, false },
98 | { dogs = 3 },
99 | { dogs = 3, cats = 4 },
100 | { dogs = 3, 5 },
101 | }
102 | for i, t in ipairs(list) do
103 | for i = 1, 10 do
104 | assert(not isempty(t))
105 | end
106 | end
107 | print("ok")
108 |
109 | --- jv
110 | --- out
111 | ok
112 | --- err
113 | [TRACE 1 test.lua:14 loop]
114 | [TRACE 2 test.lua:13 -> 1]
115 |
--------------------------------------------------------------------------------
/t/iter.t:
--------------------------------------------------------------------------------
1 | # vim: set ss=4 ft= sw=4 et sts=4 ts=4:
2 |
3 | use lib '.';
4 | use t::TestLJ;
5 |
6 | plan tests => 3 * blocks();
7 |
8 | run_tests();
9 |
10 | __DATA__
11 |
12 | === TEST 1: pairs() loop jit
13 | --- jv
14 | --- lua
15 | jit.opt.start("minstitch=1", "hotloop=2")
16 | local tb = {}
17 | for i = 1, 100 do
18 | local s = "a" .. i
19 | tb[s] = i
20 | end
21 | local total = 0
22 | for k, v in pairs(tb) do
23 | total = total + tb[k]
24 | end
25 | print("total = " .. total)
26 | --- out
27 | total = 5050
28 | --- err eval
29 | qr#\Q[TRACE 1 test.lua:3 loop]
30 | [TRACE 2 test.lua:8 loop]
31 | \E(\Q[TRACE 3 (2/1) test.lua:8 stitch print]
32 | \E)?#ms
33 |
34 |
35 |
36 | === TEST 2: explicit next() in loops
37 | --- jv
38 | --- lua
39 | jit.opt.start("minstitch=1", "hotloop=2")
40 | local tb = {}
41 | for i = 1, 100 do
42 | local s = "a" .. i
43 | tb[s] = i
44 | end
45 | local function f(tb, k)
46 | if not next(tb) then
47 | return nil
48 | end
49 | -- print("k = " .. k)
50 | return k, tb["a" .. k]
51 | end
52 | local total = 0
53 | for i = 1, 100 do
54 | local k, v = f(tb, i)
55 | if not v then
56 | break
57 | end
58 | total = total + v
59 | end
60 | print("total = " .. total)
61 | --- out
62 | total = 5050
63 | --- err
64 | [TRACE 1 test.lua:3 loop]
65 | [TRACE 2 test.lua:15 loop]
66 |
67 |
68 |
69 | === TEST 3: custom lua iterator
70 | --- jv
71 | --- lua
72 | jit.opt.start("minstitch=1", "hotloop=2")
73 | local tb = {}
74 | for i = 1, 100 do
75 | local s = "a" .. i
76 | tb[s] = i
77 | end
78 | local iter
79 | function iter2(tb, k)
80 | if k >= 100 then
81 | return nil
82 | end
83 | return k + 1, tb["a" .. (k + 1)]
84 | end
85 |
86 | function iter(tb, k)
87 | -- print("tb = " .. tostring(tb))
88 | -- print("key = " .. tostring(k))
89 | if k == nil then
90 | return iter2, tb, 0
91 | end
92 | error("bad")
93 | end
94 | local total = 0
95 | for k, v in iter(tb) do
96 | if not v then
97 | print("value is nil for key " .. tostring(k))
98 | end
99 | total = total + v
100 | end
101 | print("total = " .. total)
102 | --- out
103 | total = 5050
104 | --- err
105 | [TRACE 1 test.lua:3 loop]
106 | [TRACE 2 test.lua:24 loop]
107 |
--------------------------------------------------------------------------------
/t/nkeys.t:
--------------------------------------------------------------------------------
1 | # vim: set ss=4 ft= sw=4 et sts=4 ts=4:
2 |
3 | use lib '.';
4 | use t::TestLJ;
5 |
6 | plan tests => 3 * blocks();
7 |
8 | run_tests();
9 |
10 | __DATA__
11 |
12 | === TEST 1: hash table, interpreted
13 | --- lua
14 | jit.off()
15 | local new_tab = require "table.new"
16 | local assert = assert
17 | local nkeys = require "table.nkeys"
18 | print(nkeys(new_tab(0, 4)))
19 | print(nkeys({}))
20 | print(nkeys({ cats = 4 }))
21 | print(nkeys({ dogs = 3, cats = 4 }))
22 | print(nkeys({ dogs = nil, cats = 4 }))
23 | --- jv
24 | --- out
25 | 0
26 | 0
27 | 1
28 | 2
29 | 1
30 | --- err
31 |
32 |
33 |
34 | === TEST 2: hash table, JIT
35 | --- lua
36 | jit.on()
37 | jit.opt.start("minstitch=100000", "hotloop=2")
38 |
39 | local new_tab = require "table.new"
40 | local assert = assert
41 | local nkeys = require "table.nkeys"
42 |
43 | local list = {
44 | new_tab(0, 4),
45 | {},
46 | { cats = 4 },
47 | { dogs = 3, cats = 4 },
48 | { dogs = nil, cats = 4 },
49 | }
50 |
51 | for i, t in ipairs(list) do
52 | local total = 0
53 | for i = 1, 10 do
54 | total = total + nkeys(t)
55 | end
56 | print(total)
57 | end
58 | --- jv
59 | --- out
60 | 0
61 | 0
62 | 10
63 | 20
64 | 10
65 | --- err
66 | [TRACE 1 test.lua:18 loop]
67 | [TRACE 2 test.lua:16 -> 1]
68 |
69 |
70 |
71 | === TEST 3: pure arrays, interpreted
72 | --- lua
73 | jit.off()
74 | local new_tab = require "table.new"
75 | local assert = assert
76 | local nkeys = require "table.nkeys"
77 | print(nkeys(new_tab(5, 0)))
78 | print(nkeys({}))
79 | print(nkeys({ "cats" }))
80 | print(nkeys({ "dogs", 3, "cats", 4 }))
81 | print(nkeys({ "dogs", nil, "cats", 4 }))
82 | --- jv
83 | --- out
84 | 0
85 | 0
86 | 1
87 | 4
88 | 3
89 | --- err
90 |
91 |
92 |
93 | === TEST 4: pure array, JIT
94 | --- lua
95 | jit.on()
96 | jit.opt.start("minstitch=100000", "hotloop=2")
97 |
98 | local new_tab = require "table.new"
99 | local assert = assert
100 | local nkeys = require "table.nkeys"
101 |
102 | local list = {
103 | new_tab(0, 4),
104 | {},
105 | { 3 },
106 | { "cats", 4 },
107 | { "dogs", 3, "cats", 4 },
108 | { "dogs", nil, "cats", 4 },
109 | }
110 |
111 | for i, t in ipairs(list) do
112 | local total = 0
113 | for i = 1, 10 do
114 | total = total + nkeys(t)
115 | end
116 | print(total)
117 | end
118 | --- jv
119 | --- out
120 | 0
121 | 0
122 | 10
123 | 20
124 | 40
125 | 30
126 | --- err
127 | [TRACE 1 test.lua:19 loop]
128 | [TRACE 2 test.lua:17 -> 1]
129 |
130 |
131 |
132 | === TEST 5: mixing array and hash table, interpreted
133 | --- lua
134 | jit.off()
135 | local new_tab = require "table.new"
136 | local assert = assert
137 | local nkeys = require "table.nkeys"
138 | print(nkeys({ cats = 4, 5, 6 }))
139 | print(nkeys({ nil, "foo", dogs = 3, cats = 4 }))
140 | --- jv
141 | --- out
142 | 3
143 | 3
144 | --- err
145 |
146 |
147 |
148 | === TEST 6: mixing array & hash, JIT
149 | --- lua
150 | jit.on()
151 | jit.opt.start("minstitch=100000", "hotloop=2")
152 |
153 | local new_tab = require "table.new"
154 | local assert = assert
155 | local nkeys = require "table.nkeys"
156 |
157 | local list = {
158 | { cats = 4, 5, 6 },
159 | { nil, "foo", dogs = 3, cats = 4 },
160 | }
161 |
162 | for i, t in ipairs(list) do
163 | local total = 0
164 | for i = 1, 10 do
165 | total = total + nkeys(t)
166 | end
167 | print(total)
168 | end
169 | --- jv
170 | --- out
171 | 30
172 | 30
173 | --- err
174 | [TRACE 1 test.lua:15 loop]
175 | [TRACE 2 test.lua:13 -> 1]
176 |
--------------------------------------------------------------------------------
/t/prngstate.t:
--------------------------------------------------------------------------------
1 | # vim: set ss=4 ft= sw=4 et sts=4 ts=4:
2 |
3 | use lib '.';
4 | use t::TestLJ;
5 |
6 | plan tests => 3 * blocks();
7 |
8 | run_tests();
9 |
10 | __DATA__
11 |
12 | === TEST 1: interpreted (sanity)
13 | --- lua
14 | jit.off()
15 |
16 | function print_array(a)
17 | local out = a[1]
18 | for i=2,#a do
19 | out = out.." "..tostring(a[i])
20 | end
21 | print(out)
22 | end
23 |
24 | jit.prngstate({32})
25 | print_array(jit.prngstate({56,1,7}))
26 | print_array(jit.prngstate({423,432,432,423,56,867,35,5347}))
27 | print_array(jit.prngstate())
28 | print_array(jit.prngstate({423,432,432,423,56,867,35,5347,452}))
29 | --- out
30 | 32 0 0 0 0 0 0 0
31 | 56 1 7 0 0 0 0 0
32 | 423 432 432 423 56 867 35 5347
33 | --- jv
34 | --- err
35 | bad argument #1 to 'prngstate' (PRNG state must be an array with up to 8 integers or an integer)
36 | --- exit: 1
37 |
38 |
39 |
40 | === TEST 2: JIT (set)
41 | --- lua
42 | jit.opt.start("minstitch=100000", "hotloop=2")
43 |
44 | for i = 1, 50 do
45 | jit.prngstate({i})
46 | end
47 | print('ok')
48 | --- out
49 | ok
50 | --- jv
51 | --- err eval
52 | qr/trace too short at test.lua:4/
53 |
54 |
55 |
56 | === TEST 3: PRNG state can be an integer
57 | --- lua
58 | function print_array(a)
59 | local out = a[1]
60 | for i=2,#a do
61 | out = out.." "..tostring(a[i])
62 | end
63 | print(out)
64 | end
65 |
66 | jit.prngstate(0)
67 | print_array(jit.prngstate(30))
68 | print_array(jit.prngstate(32))
69 | print_array(jit.prngstate(4294967296)) -- 2 ** 32
70 | --- out
71 | 0 0 0 0 0 0 0 0
72 | 30 0 0 0 0 0 0 0
73 | --- jv
74 | --- err
75 | bad argument #1 to 'prngstate' (PRNG state must be an array with up to 8 integers or an integer)
76 | --- exit: 1
77 |
--------------------------------------------------------------------------------
/t/table-clone.t:
--------------------------------------------------------------------------------
1 | # vim:ft=
2 |
3 | use lib '.';
4 | use t::TestLJ;
5 |
6 | plan tests => 3 * blocks();
7 |
8 | run_tests();
9 |
10 | __DATA__
11 |
12 | === TEST 1: clone table
13 | --- lua
14 | jit.off()
15 | local clone = require "table.clone"
16 | local t = {
17 | k = {
18 | a = 1,
19 | b = 2,
20 | },
21 | }
22 |
23 | local t1 = clone(t)
24 | assert(type(t1.k) == "table")
25 | print("ok")
26 |
27 | --- jv
28 | --- out
29 | ok
30 | --- err
31 |
32 |
33 |
34 | === TEST 2: empty tables - JIT
35 | --- lua
36 | jit.on()
37 | require "jit.opt".start("hotloop=3")
38 | local clone = require "table.clone"
39 | local t = {
40 | k = {
41 | a = 1,
42 | b = 2,
43 | },
44 | }
45 |
46 | for i = 1, 10 do
47 | local t1 = clone(t)
48 | assert(type(t1) == "table")
49 | end
50 | print("ok")
51 |
52 | --- jv
53 | --- out
54 | ok
55 | --- err
56 | [TRACE 1 test.lua:11 loop]
57 |
--------------------------------------------------------------------------------