├── .gitignore ├── COPYRIGHT ├── Makefile ├── README ├── README.md ├── build-logs ├── build-output-macos-x86-64.txt ├── build-output-mingw.txt ├── build-output-notes.txt ├── build-output-tags.txt └── build-output.txt ├── doc ├── bluequad-print.css ├── bluequad.css ├── contact.html ├── ext_c_api.html ├── ext_ffi.html ├── ext_ffi_api.html ├── ext_ffi_semantics.html ├── ext_ffi_tutorial.html ├── ext_jit.html ├── extensions.html ├── faq.html ├── img │ └── contact.png ├── install.html ├── luajit.html ├── running.html └── status.html ├── dynasm ├── dasm_arm.h ├── dasm_arm.lua ├── dasm_mips.h ├── dasm_mips.lua ├── dasm_ppc.h ├── dasm_ppc.lua ├── dasm_proto.h ├── dasm_x64.lua ├── dasm_x86.h ├── dasm_x86.lua └── dynasm.lua ├── etc ├── luajit.1 └── luajit.pc ├── meson.build ├── meson_options.txt └── src ├── .gitignore ├── Makefile ├── Makefile.dep ├── host ├── .gitignore ├── README ├── buildvm.c ├── buildvm.h ├── buildvm_asm.c ├── buildvm_fold.c ├── buildvm_lib.c ├── buildvm_peobj.c ├── genminilua.lua ├── meson.build └── minilua.c ├── jit ├── .gitignore ├── bc.lua ├── bcsave.lua ├── dis_arm.lua ├── dis_mips.lua ├── dis_mipsel.lua ├── dis_ppc.lua ├── dis_x64.lua ├── dis_x86.lua ├── dump.lua ├── meson.build └── v.lua ├── lauxlib.h ├── lib_aux.c ├── lib_base.c ├── lib_bit.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.supp ├── lj_alloc.c ├── lj_alloc.h ├── lj_api.c ├── lj_arch.h ├── lj_arch_test.c ├── lj_asm.c ├── lj_asm.h ├── lj_asm_arm.h ├── lj_asm_mips.h ├── lj_asm_ppc.h ├── lj_asm_x86.h ├── lj_bc.c ├── lj_bc.h ├── lj_bcdump.h ├── lj_bcread.c ├── lj_bcwrite.c ├── 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_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_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_record.c ├── lj_record.h ├── lj_snap.c ├── lj_snap.h ├── lj_state.c ├── lj_state.h ├── lj_str.c ├── lj_str.h ├── lj_strscan.c ├── lj_strscan.h ├── lj_tab.c ├── lj_tab.h ├── lj_target.h ├── lj_target_arm.h ├── lj_target_mips.h ├── lj_target_ppc.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.h ├── lualib.h ├── meson.build ├── msvcbuild.bat ├── ps4build.bat ├── psvitabuild.bat ├── vm_arm.dasc ├── vm_mips.dasc ├── vm_ppc.dasc ├── vm_ppcspe.dasc ├── vm_x86.dasc └── xedkbuild.bat /.gitignore: -------------------------------------------------------------------------------- 1 | *.[oa] 2 | *.so 3 | *.obj 4 | *.lib 5 | *.exp 6 | *.dll 7 | *.exe 8 | *.manifest 9 | *.dmp 10 | *.swp 11 | .tags 12 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | =============================================================================== 2 | LuaJIT -- a Just-In-Time Compiler for Lua. https://luajit.org/ 3 | 4 | Copyright (C) 2005-2022 Mike Pall. All rights reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | 24 | [ MIT license: https://www.opensource.org/licenses/mit-license.php ] 25 | 26 | =============================================================================== 27 | [ LuaJIT includes code from Lua 5.1/5.2, which has this license statement: ] 28 | 29 | Copyright (C) 1994-2012 Lua.org, PUC-Rio. 30 | 31 | Permission is hereby granted, free of charge, to any person obtaining a copy 32 | of this software and associated documentation files (the "Software"), to deal 33 | in the Software without restriction, including without limitation the rights 34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 35 | copies of the Software, and to permit persons to whom the Software is 36 | furnished to do so, subject to the following conditions: 37 | 38 | The above copyright notice and this permission notice shall be included in 39 | all copies or substantial portions of the Software. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 47 | THE SOFTWARE. 48 | 49 | =============================================================================== 50 | [ LuaJIT includes code from dlmalloc, which has this license statement: ] 51 | 52 | This is a version (aka dlmalloc) of malloc/free/realloc written by 53 | Doug Lea and released to the public domain, as explained at 54 | https://creativecommons.org/licenses/publicdomain 55 | 56 | =============================================================================== 57 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # LuaJIT top level Makefile for installation. Requires GNU Make. 3 | # 4 | # Please read doc/install.html before changing any variables! 5 | # 6 | # Suitable for POSIX platforms (Linux, *BSD, OSX etc.). 7 | # Note: src/Makefile has many more configurable options. 8 | # 9 | # ##### This Makefile is NOT useful for Windows! ##### 10 | # For MSVC, please follow the instructions given in src/msvcbuild.bat. 11 | # For MinGW and Cygwin, cd to src and run make with the Makefile there. 12 | # 13 | # Copyright (C) 2005-2022 Mike Pall. See Copyright Notice in luajit.h 14 | ############################################################################## 15 | 16 | MAJVER= 2 17 | MINVER= 0 18 | RELVER= 5 19 | VERSION= $(MAJVER).$(MINVER).$(RELVER) 20 | ABIVER= 5.1 21 | 22 | ############################################################################## 23 | # 24 | # Change the installation path as needed. This automatically adjusts 25 | # the paths in src/luaconf.h, too. Note: PREFIX must be an absolute path! 26 | # 27 | export PREFIX= /usr/local 28 | export MULTILIB= lib 29 | ############################################################################## 30 | 31 | DPREFIX= $(DESTDIR)$(PREFIX) 32 | INSTALL_BIN= $(DPREFIX)/bin 33 | INSTALL_LIB= $(DPREFIX)/$(MULTILIB) 34 | INSTALL_SHARE= $(DPREFIX)/share 35 | INSTALL_INC= $(DPREFIX)/include/luajit-$(MAJVER).$(MINVER) 36 | 37 | INSTALL_LJLIBD= $(INSTALL_SHARE)/luajit-$(VERSION) 38 | INSTALL_JITLIB= $(INSTALL_LJLIBD)/jit 39 | INSTALL_LMODD= $(INSTALL_SHARE)/lua 40 | INSTALL_LMOD= $(INSTALL_LMODD)/$(ABIVER) 41 | INSTALL_CMODD= $(INSTALL_LIB)/lua 42 | INSTALL_CMOD= $(INSTALL_CMODD)/$(ABIVER) 43 | INSTALL_MAN= $(INSTALL_SHARE)/man/man1 44 | INSTALL_PKGCONFIG= $(INSTALL_LIB)/pkgconfig 45 | 46 | INSTALL_TNAME= luajit-$(VERSION) 47 | INSTALL_TSYMNAME= luajit 48 | INSTALL_ANAME= libluajit-$(ABIVER).a 49 | INSTALL_SOSHORT1= libluajit-$(ABIVER).so 50 | INSTALL_SOSHORT2= libluajit-$(ABIVER).so.$(MAJVER) 51 | INSTALL_SONAME= $(INSTALL_SOSHORT2).$(MINVER).$(RELVER) 52 | INSTALL_DYLIBSHORT1= libluajit-$(ABIVER).dylib 53 | INSTALL_DYLIBSHORT2= libluajit-$(ABIVER).$(MAJVER).dylib 54 | INSTALL_DYLIBNAME= libluajit-$(ABIVER).$(MAJVER).$(MINVER).$(RELVER).dylib 55 | INSTALL_PCNAME= luajit.pc 56 | 57 | INSTALL_STATIC= $(INSTALL_LIB)/$(INSTALL_ANAME) 58 | INSTALL_DYN= $(INSTALL_LIB)/$(INSTALL_SONAME) 59 | INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_SOSHORT1) 60 | INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_SOSHORT2) 61 | INSTALL_T= $(INSTALL_BIN)/$(INSTALL_TNAME) 62 | INSTALL_TSYM= $(INSTALL_BIN)/$(INSTALL_TSYMNAME) 63 | INSTALL_PC= $(INSTALL_PKGCONFIG)/$(INSTALL_PCNAME) 64 | 65 | INSTALL_DIRS= $(INSTALL_BIN) $(INSTALL_LIB) $(INSTALL_INC) $(INSTALL_MAN) \ 66 | $(INSTALL_PKGCONFIG) $(INSTALL_JITLIB) $(INSTALL_LMOD) $(INSTALL_CMOD) 67 | UNINSTALL_DIRS= $(INSTALL_JITLIB) $(INSTALL_LJLIBD) $(INSTALL_INC) \ 68 | $(INSTALL_LMOD) $(INSTALL_LMODD) $(INSTALL_CMOD) $(INSTALL_CMODD) 69 | 70 | RM= rm -f 71 | MKDIR= mkdir -p 72 | RMDIR= rmdir 2>/dev/null 73 | SYMLINK= ln -sf 74 | INSTALL_X= install -m 0755 75 | INSTALL_F= install -m 0644 76 | UNINSTALL= $(RM) 77 | LDCONFIG= ldconfig -n 2>/dev/null 78 | SED_PC= sed -e "s|^prefix=.*|prefix=$(PREFIX)|" \ 79 | -e "s|^multilib=.*|multilib=$(MULTILIB)|" 80 | 81 | FILE_T= luajit 82 | FILE_A= libluajit.a 83 | FILE_SO= libluajit.so 84 | FILE_MAN= luajit.1 85 | FILE_PC= luajit.pc 86 | FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h 87 | FILES_JITLIB= bc.lua v.lua dump.lua dis_x86.lua dis_x64.lua dis_arm.lua \ 88 | dis_ppc.lua dis_mips.lua dis_mipsel.lua bcsave.lua vmdef.lua 89 | 90 | ifeq (,$(findstring Windows,$(OS))) 91 | HOST_SYS:= $(shell uname -s) 92 | else 93 | HOST_SYS= Windows 94 | endif 95 | TARGET_SYS?= $(HOST_SYS) 96 | 97 | ifeq (Darwin,$(TARGET_SYS)) 98 | INSTALL_SONAME= $(INSTALL_DYLIBNAME) 99 | INSTALL_SOSHORT1= $(INSTALL_DYLIBSHORT1) 100 | INSTALL_SOSHORT2= $(INSTALL_DYLIBSHORT2) 101 | LDCONFIG= : 102 | endif 103 | 104 | ############################################################################## 105 | 106 | INSTALL_DEP= src/luajit 107 | 108 | default all $(INSTALL_DEP): 109 | @echo "==== Building LuaJIT $(VERSION) ====" 110 | $(MAKE) -C src 111 | @echo "==== Successfully built LuaJIT $(VERSION) ====" 112 | 113 | install: $(INSTALL_DEP) 114 | @echo "==== Installing LuaJIT $(VERSION) to $(PREFIX) ====" 115 | $(MKDIR) $(INSTALL_DIRS) 116 | cd src && $(INSTALL_X) $(FILE_T) $(INSTALL_T) 117 | cd src && test -f $(FILE_A) && $(INSTALL_F) $(FILE_A) $(INSTALL_STATIC) || : 118 | $(RM) $(INSTALL_TSYM) $(INSTALL_DYN) $(INSTALL_SHORT1) $(INSTALL_SHORT2) 119 | cd src && test -f $(FILE_SO) && \ 120 | $(INSTALL_X) $(FILE_SO) $(INSTALL_DYN) && \ 121 | ( $(LDCONFIG) $(INSTALL_LIB) || : ) && \ 122 | $(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT1) && \ 123 | $(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT2) || : 124 | cd etc && $(INSTALL_F) $(FILE_MAN) $(INSTALL_MAN) 125 | cd etc && $(SED_PC) $(FILE_PC) > $(FILE_PC).tmp && \ 126 | $(INSTALL_F) $(FILE_PC).tmp $(INSTALL_PC) && \ 127 | $(RM) $(FILE_PC).tmp 128 | cd src && $(INSTALL_F) $(FILES_INC) $(INSTALL_INC) 129 | cd src/jit && $(INSTALL_F) $(FILES_JITLIB) $(INSTALL_JITLIB) 130 | $(SYMLINK) $(INSTALL_TNAME) $(INSTALL_TSYM) 131 | @echo "==== Successfully installed LuaJIT $(VERSION) to $(PREFIX) ====" 132 | 133 | uninstall: 134 | @echo "==== Uninstalling LuaJIT $(VERSION) from $(PREFIX) ====" 135 | $(UNINSTALL) $(INSTALL_TSYM) $(INSTALL_T) $(INSTALL_STATIC) $(INSTALL_DYN) $(INSTALL_SHORT1) $(INSTALL_SHORT2) $(INSTALL_MAN)/$(FILE_MAN) $(INSTALL_PC) 136 | for file in $(FILES_JITLIB); do \ 137 | $(UNINSTALL) $(INSTALL_JITLIB)/$$file; \ 138 | done 139 | for file in $(FILES_INC); do \ 140 | $(UNINSTALL) $(INSTALL_INC)/$$file; \ 141 | done 142 | $(LDCONFIG) $(INSTALL_LIB) 143 | $(RMDIR) $(UNINSTALL_DIRS) || : 144 | @echo "==== Successfully uninstalled LuaJIT $(VERSION) from $(PREFIX) ====" 145 | 146 | ############################################################################## 147 | 148 | amalg: 149 | @echo "Building LuaJIT $(VERSION)" 150 | $(MAKE) -C src amalg 151 | 152 | clean: 153 | $(MAKE) -C src clean 154 | 155 | .PHONY: all install amalg clean 156 | 157 | ############################################################################## 158 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | README for LuaJIT 2.0.5 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-2022 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | *Meson build for LuaJIT 2* 2 | 3 | This repository mirrors the source code for LuaJIT 2 with the addition of a Meson build. 4 | 5 | You can find more information about LuaJIT in the [LuaJIT's homepage](http://luajit.org/). 6 | 7 | ## Why Meson ? 8 | 9 | Because it is better than Makefiles and works better with [Little Library Helper](https://github.com/franko/lhelper) to easily build and install LuaJIT on Linux or Windows. 10 | 11 | One of the practical reason that pushed me to write a Meson build for LuaJIT was that the .pc files installed with the original Makefiles was installed in the wrong directory on Debian. Even more important, the Makefile is not accurate when it comes to install the library. 12 | 13 | ## How to use it? 14 | 15 | From the source directory: 16 | 17 | ```sh 18 | meson setup build 19 | ninja -C build 20 | ninja -C build install 21 | ``` 22 | more information from the [Meson Quick guide](https://mesonbuild.com/Quick-guide.html). 23 | 24 | ## What is LuaJIT? (extract from LuaJIT's README) 25 | 26 | LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language. 27 | 28 | Project Homepage: http://luajit.org/ 29 | 30 | LuaJIT is Copyright (C) 2005-2017 Mike Pall. 31 | LuaJIT is free software, released under the MIT license. 32 | See full Copyright Notice in the COPYRIGHT file or in luajit.h. 33 | 34 | Documentation for LuaJIT is available in HTML format. 35 | Please point your favorite browser to: 36 | 37 | doc/luajit.html 38 | -------------------------------------------------------------------------------- /build-logs/build-output-tags.txt: -------------------------------------------------------------------------------- 1 | ==== Building LuaJIT 2.0.5 ==== 2 | make -C src 3 | make[1]: Entering directory '/home/francesco/dev/luajit-2.0/src' 4 | HOSTCC host/minilua.o 5 | HOSTLINK host/minilua 6 | DYNASM host/buildvm_arch.h 7 | HOSTCC host/buildvm.o 8 | HOSTCC host/buildvm_asm.o 9 | HOSTCC host/buildvm_peobj.o 10 | HOSTCC host/buildvm_lib.o 11 | HOSTCC host/buildvm_fold.o 12 | HOSTLINK host/buildvm 13 | BUILDVM lj_vm.s 14 | ASM lj_vm.o 15 | CC lj_gc.o 16 | BUILDVM lj_ffdef.h 17 | CC lj_err.o 18 | CC lj_char.o 19 | BUILDVM lj_bcdef.h 20 | CC lj_bc.o 21 | CC lj_obj.o 22 | CC lj_str.o 23 | CC lj_tab.o 24 | CC lj_func.o 25 | CC lj_udata.o 26 | CC lj_meta.o 27 | CC lj_debug.o 28 | CC lj_state.o 29 | CC lj_dispatch.o 30 | CC lj_vmevent.o 31 | CC lj_vmmath.o 32 | CC lj_strscan.o 33 | CC lj_api.o 34 | CC lj_lex.o 35 | CC lj_parse.o 36 | CC lj_bcread.o 37 | CC lj_bcwrite.o 38 | CC lj_load.o 39 | CC lj_ir.o 40 | CC lj_opt_mem.o 41 | BUILDVM lj_folddef.h 42 | CC lj_opt_fold.o 43 | CC lj_opt_narrow.o 44 | CC lj_opt_dce.o 45 | CC lj_opt_loop.o 46 | CC lj_opt_split.o 47 | CC lj_opt_sink.o 48 | CC lj_mcode.o 49 | CC lj_snap.o 50 | CC lj_record.o 51 | CC lj_crecord.o 52 | BUILDVM lj_recdef.h 53 | CC lj_ffrecord.o 54 | CC lj_asm.o 55 | CC lj_trace.o 56 | CC lj_gdbjit.o 57 | CC lj_ctype.o 58 | CC lj_cdata.o 59 | CC lj_cconv.o 60 | CC lj_ccall.o 61 | CC lj_ccallback.o 62 | CC lj_carith.o 63 | CC lj_clib.o 64 | CC lj_cparse.o 65 | CC lj_lib.o 66 | CC lj_alloc.o 67 | CC lib_aux.o 68 | BUILDVM lj_libdef.h 69 | CC lib_base.o 70 | CC lib_math.o 71 | CC lib_bit.o 72 | CC lib_string.o 73 | CC lib_table.o 74 | CC lib_io.o 75 | CC lib_os.o 76 | CC lib_package.o 77 | CC lib_debug.o 78 | CC lib_jit.o 79 | CC lib_ffi.o 80 | CC lib_init.o 81 | AR libluajit.a 82 | CC luajit.o 83 | BUILDVM jit/vmdef.lua 84 | DYNLINK libluajit.so 85 | LINK luajit 86 | OK Successfully built LuaJIT 87 | make[1]: Leaving directory '/home/francesco/dev/luajit-2.0/src' 88 | ==== Successfully built LuaJIT 2.0.5 ==== 89 | -------------------------------------------------------------------------------- /doc/bluequad-print.css: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2004-2022 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 |
13 | Lua 14 |
15 | 18 | 54 |
55 |

56 | If you want to report bugs, propose fixes or suggest enhancements, 57 | please use the 58 | » GitHub issue tracker. 59 |

60 |

61 | Please send general questions to the 62 | » LuaJIT mailing list. 63 |

64 |

65 | You can also send any questions you have directly to me: 66 |

67 | 68 | 76 | 80 | 84 | 85 |

Copyright

86 |

87 | All documentation is 88 | Copyright © 2005-2022 Mike Pall. 89 |

90 | 91 | 92 |
93 |
94 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /doc/ext_c_api.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Lua/C API Extensions 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | Lua 14 |
15 | 18 | 54 |
55 |

56 | LuaJIT adds some extensions to the standard Lua/C API. The LuaJIT include 57 | directory must be in the compiler search path (-Ipath) 58 | to be able to include the required header for C code: 59 |

60 |
 61 | #include "luajit.h"
 62 | 
63 |

64 | Or for C++ code: 65 |

66 |
 67 | #include "lua.hpp"
 68 | 
69 | 70 |

luaJIT_setmode(L, idx, mode) 71 | — Control VM

72 |

73 | This is a C API extension to allow control of the VM from C code. The 74 | full prototype of LuaJIT_setmode is: 75 |

76 |
 77 | LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
 78 | 
79 |

80 | The returned status is either success (1) or failure (0). 81 | The second argument is either 0 or a stack index (similar to the 82 | other Lua/C API functions). 83 |

84 |

85 | The third argument specifies the mode, which is 'or'ed with a flag. 86 | The flag can be LUAJIT_MODE_OFF to turn a feature off, 87 | LUAJIT_MODE_ON to turn a feature on, or 88 | LUAJIT_MODE_FLUSH to flush cached code. 89 |

90 |

91 | The following modes are defined: 92 |

93 | 94 |

luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|flag)

95 |

96 | Turn the whole JIT compiler on or off or flush the whole cache of compiled code. 97 |

98 | 99 |

luaJIT_setmode(L, idx, LUAJIT_MODE_FUNC|flag)
100 | luaJIT_setmode(L, idx, LUAJIT_MODE_ALLFUNC|flag)
101 | luaJIT_setmode(L, idx, LUAJIT_MODE_ALLSUBFUNC|flag)

102 |

103 | This sets the mode for the function at the stack index idx or 104 | the parent of the calling function (idx = 0). It either 105 | enables JIT compilation for a function, disables it and flushes any 106 | already compiled code or only flushes already compiled code. This 107 | applies recursively to all sub-functions of the function with 108 | LUAJIT_MODE_ALLFUNC or only to the sub-functions with 109 | LUAJIT_MODE_ALLSUBFUNC. 110 |

111 | 112 |

luaJIT_setmode(L, trace,
113 |   LUAJIT_MODE_TRACE|LUAJIT_MODE_FLUSH)

114 |

115 | Flushes the specified root trace and all of its side traces from the cache. 116 | The code for the trace will be retained as long as there are any other 117 | traces which link to it. 118 |

119 | 120 |

luaJIT_setmode(L, idx, LUAJIT_MODE_WRAPCFUNC|flag)

121 |

122 | This mode defines a wrapper function for calls to C functions. If 123 | called with LUAJIT_MODE_ON, the stack index at idx 124 | must be a lightuserdata object holding a pointer to the wrapper 125 | function. From now on all C functions are called through the wrapper 126 | function. If called with LUAJIT_MODE_OFF this mode is turned 127 | off and all C functions are directly called. 128 |

129 |

130 | The wrapper function can be used for debugging purposes or to catch 131 | and convert foreign exceptions. But please read the section on 132 | C++ exception interoperability 133 | first. Recommended usage can be seen in this C++ code excerpt: 134 |

135 |
136 | #include <exception>
137 | #include "lua.hpp"
138 | 
139 | // Catch C++ exceptions and convert them to Lua error messages.
140 | // Customize as needed for your own exception classes.
141 | static int wrap_exceptions(lua_State *L, lua_CFunction f)
142 | {
143 |   try {
144 |     return f(L);  // Call wrapped function and return result.
145 |   } catch (const char *s) {  // Catch and convert exceptions.
146 |     lua_pushstring(L, s);
147 |   } catch (std::exception& e) {
148 |     lua_pushstring(L, e.what());
149 |   } catch (...) {
150 |     lua_pushliteral(L, "caught (...)");
151 |   }
152 |   return lua_error(L);  // Rethrow as a Lua error.
153 | }
154 | 
155 | static int myinit(lua_State *L)
156 | {
157 |   ...
158 |   // Define wrapper function and enable it.
159 |   lua_pushlightuserdata(L, (void *)wrap_exceptions);
160 |   luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
161 |   lua_pop(L, 1);
162 |   ...
163 | }
164 | 
165 |

166 | Note that you can only define a single global wrapper function, 167 | so be careful when using this mechanism from multiple C++ modules. 168 | Also note that this mechanism is not without overhead. 169 |

170 |
171 |
172 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /doc/ext_jit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jit.* Library 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | Lua 14 |
15 | 18 | 54 |
55 |

56 | The functions in this built-in module control the behavior of the JIT 57 | compiler engine. Note that JIT-compilation is fully automatic — 58 | you probably won't need to use any of the following functions unless 59 | you have special needs. 60 |

61 | 62 |

jit.on()
63 | jit.off()

64 |

65 | Turns the whole JIT compiler on (default) or off. 66 |

67 |

68 | These functions are typically used with the command line options 69 | -j on or -j off. 70 |

71 | 72 |

jit.flush()

73 |

74 | Flushes the whole cache of compiled code. 75 |

76 | 77 |

jit.on(func|true [,true|false])
78 | jit.off(func|true [,true|false])
79 | jit.flush(func|true [,true|false])

80 |

81 | jit.on enables JIT compilation for a Lua function (this is 82 | the default). 83 |

84 |

85 | jit.off disables JIT compilation for a Lua function and 86 | flushes any already compiled code from the code cache. 87 |

88 |

89 | jit.flush flushes the code, but doesn't affect the 90 | enable/disable status. 91 |

92 |

93 | The current function, i.e. the Lua function calling this library 94 | function, can also be specified by passing true as the first 95 | argument. 96 |

97 |

98 | If the second argument is true, JIT compilation is also 99 | enabled, disabled or flushed recursively for all sub-functions of a 100 | function. With false only the sub-functions are affected. 101 |

102 |

103 | The jit.on and jit.off functions only set a flag 104 | which is checked when the function is about to be compiled. They do 105 | not trigger immediate compilation. 106 |

107 |

108 | Typical usage is jit.off(true, true) in the main chunk 109 | of a module to turn off JIT compilation for the whole module for 110 | debugging purposes. 111 |

112 | 113 |

jit.flush(tr)

114 |

115 | Flushes the root trace, specified by its number, and all of its side 116 | traces from the cache. The code for the trace will be retained as long 117 | as there are any other traces which link to it. 118 |

119 | 120 |

status, ... = jit.status()

121 |

122 | Returns the current status of the JIT compiler. The first result is 123 | either true or false if the JIT compiler is turned 124 | on or off. The remaining results are strings for CPU-specific features 125 | and enabled optimizations. 126 |

127 | 128 |

jit.version

129 |

130 | Contains the LuaJIT version string. 131 |

132 | 133 |

jit.version_num

134 |

135 | Contains the version number of the LuaJIT core. Version xx.yy.zz 136 | is represented by the decimal number xxyyzz. 137 |

138 | 139 |

jit.os

140 |

141 | Contains the target OS name: 142 | "Windows", "Linux", "OSX", "BSD", "POSIX" or "Other". 143 |

144 | 145 |

jit.arch

146 |

147 | Contains the target architecture name: 148 | "x86", "x64", "arm", "ppc", "ppcspe", or "mips". 149 |

150 | 151 |

jit.opt.* — JIT compiler optimization control

152 |

153 | This sub-module provides the backend for the -O command line 154 | option. 155 |

156 |

157 | You can also use it programmatically, e.g.: 158 |

159 |
160 | jit.opt.start(2) -- same as -O2
161 | jit.opt.start("-dce")
162 | jit.opt.start("hotloop=10", "hotexit=2")
163 | 
164 |

165 | Unlike in LuaJIT 1.x, the module is built-in and 166 | optimization is turned on by default! 167 | It's no longer necessary to run require("jit.opt").start(), 168 | which was one of the ways to enable optimization. 169 |

170 | 171 |

jit.util.* — JIT compiler introspection

172 |

173 | This sub-module holds functions to introspect the bytecode, generated 174 | traces, the IR and the generated machine code. The functionality 175 | provided by this module is still in flux and therefore undocumented. 176 |

177 |

178 | The debug modules -jbc, -jv and -jdump make 179 | extensive use of these functions. Please check out their source code, 180 | if you want to know more. 181 |

182 |
183 |
184 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /doc/img/contact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/franko/luajit/87bd8e34796f4c89274f57b613bffe719d61b052/doc/img/contact.png -------------------------------------------------------------------------------- /doc/status.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Status 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | 15 |
16 | Lua 17 |
18 | 21 | 57 |
58 |

59 | This documentation is for LuaJIT 2.0.5. Please check the doc 60 | directory in each git branch for the version-specific documentation. 61 |

62 |

63 | The currently developed branches are LuaJIT 2.1 and LuaJIT 2.0. 64 |

65 |

66 | LuaJIT 2.0 is in feature-freeze — new features will only 67 | be added to LuaJIT 2.1. 68 |

69 | 70 |

Current Status

71 |

72 | LuaJIT ought to run all Lua 5.1-compatible source code just fine. 73 | It's considered a serious bug if the VM crashes or produces unexpected 74 | results — please report this. 75 |

76 |

77 | Known incompatibilities and issues in LuaJIT 2.0: 78 |

79 | 98 |
99 |
100 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /dynasm/dasm_proto.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** DynASM encoding engine prototypes. 3 | ** Copyright (C) 2005-2022 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.3.0" 14 | #define DASM_VERSION 10300 /* 1.3.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-2022 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-2022 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=0 4 | relver=5 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 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('luajit', 'c', version : '2.0.5', default_options : ['c_winlibs=']) 2 | 3 | pkg = import('pkgconfig') 4 | 5 | cc = meson.get_compiler('c') 6 | libm = cc.find_library('m', required : false) 7 | libdl = cc.find_library('dl', required : false) 8 | luajit_dependencies = [libm, libdl] 9 | 10 | luajit_source_dir = include_directories('src') 11 | luajit_abiver = '51' 12 | 13 | dynasm = files('dynasm/dynasm.lua') 14 | 15 | install_man('etc/luajit.1') 16 | 17 | subdir('src') 18 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('portable', type : 'boolean', value : false, description: 'portable install in a single directory') 2 | option('app', type : 'boolean', value : true, description: 'Build the luajit executable') 3 | 4 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | luajit 2 | lj_bcdef.h 3 | lj_ffdef.h 4 | lj_libdef.h 5 | lj_recdef.h 6 | lj_folddef.h 7 | lj_vm.s 8 | -------------------------------------------------------------------------------- /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-2022 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 *dasm_ident; 86 | const char *dasm_arch; 87 | /* Relocations. */ 88 | BuildReloc reloc[BUILD_MAX_RELOC]; 89 | } BuildCtx; 90 | 91 | extern void owrite(BuildCtx *ctx, const void *ptr, size_t sz); 92 | extern void emit_asm(BuildCtx *ctx); 93 | extern void emit_peobj(BuildCtx *ctx); 94 | extern void emit_lib(BuildCtx *ctx); 95 | extern void emit_fold(BuildCtx *ctx); 96 | 97 | extern const char *const bc_names[]; 98 | extern const char *const ir_names[]; 99 | extern const char *const irt_names[]; 100 | extern const char *const irfpm_names[]; 101 | extern const char *const irfield_names[]; 102 | extern const char *const ircall_names[]; 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /src/host/meson.build: -------------------------------------------------------------------------------- 1 | minilua = executable('minilua', 'minilua.c', dependencies: libm, install: false, native: true) 2 | 3 | lj_arch_run = cc.run(lj_arch_test_source) 4 | if not lj_arch_run.compiled() or lj_arch_run.returncode() != 0 5 | error('error running luajit arch testing program: ' + lj_arch_run.stderr()) 6 | endif 7 | lj_arch_list = lj_arch_run.stdout().split(':') 8 | 9 | # Print output of lj_arch_test for information purpose. 10 | foreach line : lj_arch_list 11 | message(line) 12 | endforeach 13 | 14 | lj_arch = lj_arch_list[0] 15 | dasm_arch = lj_arch_list[1] 16 | buildvm_defines = lj_arch_list[2].split(',') 17 | 18 | dasm_args = [minilua, dynasm] 19 | dasm_args += lj_arch_list[3].split(',') 20 | dasm_args += ['-o', '@OUTPUT@', '@INPUT@'] 21 | 22 | vm_dasc = files('../vm_' + dasm_arch + '.dasc') 23 | 24 | buildvm_arch_h = custom_target('buildvm_arch.h', 25 | input : vm_dasc, 26 | output : 'buildvm_arch.h', 27 | command : dasm_args, 28 | ) 29 | 30 | buildvm_sources = ['buildvm.c', 'buildvm_asm.c', 'buildvm_peobj.c', 'buildvm_lib.c', 'buildvm_fold.c'] 31 | buildvm_sources += buildvm_arch_h 32 | 33 | buildvm = executable('buildvm', 34 | buildvm_sources, 35 | include_directories: luajit_source_dir, 36 | c_args: buildvm_defines, 37 | dependencies: libm, 38 | install: false, 39 | native: true 40 | ) 41 | -------------------------------------------------------------------------------- /src/jit/.gitignore: -------------------------------------------------------------------------------- 1 | vmdef.lua 2 | -------------------------------------------------------------------------------- /src/jit/bc.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------- 2 | -- LuaJIT bytecode listing module. 3 | -- 4 | -- Copyright (C) 2005-2022 Mike Pall. All rights reserved. 5 | -- Released under the MIT license. See Copyright Notice in luajit.h 6 | ---------------------------------------------------------------------------- 7 | -- 8 | -- This module lists the bytecode of a Lua function. If it's loaded by -jbc 9 | -- it hooks into the parser and lists all functions of a chunk as they 10 | -- are parsed. 11 | -- 12 | -- Example usage: 13 | -- 14 | -- luajit -jbc -e 'local x=0; for i=1,1e6 do x=x+i end; print(x)' 15 | -- luajit -jbc=- foo.lua 16 | -- luajit -jbc=foo.list foo.lua 17 | -- 18 | -- Default output is to stderr. To redirect the output to a file, pass a 19 | -- filename as an argument (use '-' for stdout) or set the environment 20 | -- variable LUAJIT_LISTFILE. The file is overwritten every time the module 21 | -- is started. 22 | -- 23 | -- This module can also be used programmatically: 24 | -- 25 | -- local bc = require("jit.bc") 26 | -- 27 | -- local function foo() print("hello") end 28 | -- 29 | -- bc.dump(foo) --> -- BYTECODE -- [...] 30 | -- print(bc.line(foo, 2)) --> 0002 KSTR 1 1 ; "hello" 31 | -- 32 | -- local out = { 33 | -- -- Do something with each line: 34 | -- write = function(t, ...) io.write(...) end, 35 | -- close = function(t) end, 36 | -- flush = function(t) end, 37 | -- } 38 | -- bc.dump(foo, out) 39 | -- 40 | ------------------------------------------------------------------------------ 41 | 42 | -- Cache some library functions and objects. 43 | local jit = require("jit") 44 | assert(jit.version_num == 20005, "LuaJIT core/library version mismatch") 45 | local jutil = require("jit.util") 46 | local vmdef = require("jit.vmdef") 47 | local bit = require("bit") 48 | local sub, gsub, format = string.sub, string.gsub, string.format 49 | local byte, band, shr = string.byte, bit.band, bit.rshift 50 | local funcinfo, funcbc, funck = jutil.funcinfo, jutil.funcbc, jutil.funck 51 | local funcuvname = jutil.funcuvname 52 | local bcnames = vmdef.bcnames 53 | local stdout, stderr = io.stdout, io.stderr 54 | 55 | ------------------------------------------------------------------------------ 56 | 57 | local function ctlsub(c) 58 | if c == "\n" then return "\\n" 59 | elseif c == "\r" then return "\\r" 60 | elseif c == "\t" then return "\\t" 61 | else return format("\\%03d", byte(c)) 62 | end 63 | end 64 | 65 | -- Return one bytecode line. 66 | local function bcline(func, pc, prefix) 67 | local ins, m = funcbc(func, pc) 68 | if not ins then return end 69 | local ma, mb, mc = band(m, 7), band(m, 15*8), band(m, 15*128) 70 | local a = band(shr(ins, 8), 0xff) 71 | local oidx = 6*band(ins, 0xff) 72 | local op = sub(bcnames, oidx+1, oidx+6) 73 | local s = format("%04d %s %-6s %3s ", 74 | pc, prefix or " ", op, ma == 0 and "" or a) 75 | local d = shr(ins, 16) 76 | if mc == 13*128 then -- BCMjump 77 | return format("%s=> %04d\n", s, pc+d-0x7fff) 78 | end 79 | if mb ~= 0 then 80 | d = band(d, 0xff) 81 | elseif mc == 0 then 82 | return s.."\n" 83 | end 84 | local kc 85 | if mc == 10*128 then -- BCMstr 86 | kc = funck(func, -d-1) 87 | kc = format(#kc > 40 and '"%.40s"~' or '"%s"', gsub(kc, "%c", ctlsub)) 88 | elseif mc == 9*128 then -- BCMnum 89 | kc = funck(func, d) 90 | if op == "TSETM " then kc = kc - 2^52 end 91 | elseif mc == 12*128 then -- BCMfunc 92 | local fi = funcinfo(funck(func, -d-1)) 93 | if fi.ffid then 94 | kc = vmdef.ffnames[fi.ffid] 95 | else 96 | kc = fi.loc 97 | end 98 | elseif mc == 5*128 then -- BCMuv 99 | kc = funcuvname(func, d) 100 | end 101 | if ma == 5 then -- BCMuv 102 | local ka = funcuvname(func, a) 103 | if kc then kc = ka.." ; "..kc else kc = ka end 104 | end 105 | if mb ~= 0 then 106 | local b = shr(ins, 24) 107 | if kc then return format("%s%3d %3d ; %s\n", s, b, d, kc) end 108 | return format("%s%3d %3d\n", s, b, d) 109 | end 110 | if kc then return format("%s%3d ; %s\n", s, d, kc) end 111 | if mc == 7*128 and d > 32767 then d = d - 65536 end -- BCMlits 112 | return format("%s%3d\n", s, d) 113 | end 114 | 115 | -- Collect branch targets of a function. 116 | local function bctargets(func) 117 | local target = {} 118 | for pc=1,1000000000 do 119 | local ins, m = funcbc(func, pc) 120 | if not ins then break end 121 | if band(m, 15*128) == 13*128 then target[pc+shr(ins, 16)-0x7fff] = true end 122 | end 123 | return target 124 | end 125 | 126 | -- Dump bytecode instructions of a function. 127 | local function bcdump(func, out, all) 128 | if not out then out = stdout end 129 | local fi = funcinfo(func) 130 | if all and fi.children then 131 | for n=-1,-1000000000,-1 do 132 | local k = funck(func, n) 133 | if not k then break end 134 | if type(k) == "proto" then bcdump(k, out, true) end 135 | end 136 | end 137 | out:write(format("-- BYTECODE -- %s-%d\n", fi.loc, fi.lastlinedefined)) 138 | local target = bctargets(func) 139 | for pc=1,1000000000 do 140 | local s = bcline(func, pc, target[pc] and "=>") 141 | if not s then break end 142 | out:write(s) 143 | end 144 | out:write("\n") 145 | out:flush() 146 | end 147 | 148 | ------------------------------------------------------------------------------ 149 | 150 | -- Active flag and output file handle. 151 | local active, out 152 | 153 | -- List handler. 154 | local function h_list(func) 155 | return bcdump(func, out) 156 | end 157 | 158 | -- Detach list handler. 159 | local function bclistoff() 160 | if active then 161 | active = false 162 | jit.attach(h_list) 163 | if out and out ~= stdout and out ~= stderr then out:close() end 164 | out = nil 165 | end 166 | end 167 | 168 | -- Open the output file and attach list handler. 169 | local function bcliston(outfile) 170 | if active then bclistoff() end 171 | if not outfile then outfile = os.getenv("LUAJIT_LISTFILE") end 172 | if outfile then 173 | out = outfile == "-" and stdout or assert(io.open(outfile, "w")) 174 | else 175 | out = stderr 176 | end 177 | jit.attach(h_list, "bc") 178 | active = true 179 | end 180 | 181 | -- Public module functions. 182 | module(...) 183 | 184 | line = bcline 185 | dump = bcdump 186 | targets = bctargets 187 | 188 | on = bcliston 189 | off = bclistoff 190 | start = bcliston -- For -j command line option. 191 | 192 | -------------------------------------------------------------------------------- /src/jit/dis_mipsel.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------- 2 | -- LuaJIT MIPSEL disassembler wrapper module. 3 | -- 4 | -- Copyright (C) 2005-2022 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 require = require 12 | 13 | module(...) 14 | 15 | local dis_mips = require(_PACKAGE.."dis_mips") 16 | 17 | create = dis_mips.create_el 18 | disass = dis_mips.disass_el 19 | regname = dis_mips.regname 20 | 21 | -------------------------------------------------------------------------------- /src/jit/dis_x64.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------- 2 | -- LuaJIT x64 disassembler wrapper module. 3 | -- 4 | -- Copyright (C) 2005-2022 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 require = require 12 | 13 | module(...) 14 | 15 | local dis_x86 = require(_PACKAGE.."dis_x86") 16 | 17 | create = dis_x86.create64 18 | disass = dis_x86.disass64 19 | regname = dis_x86.regname64 20 | 21 | -------------------------------------------------------------------------------- /src/jit/meson.build: -------------------------------------------------------------------------------- 1 | jitlib_files = ['bc.lua', 'v.lua', 'dump.lua', 'dis_x86.lua', 'dis_x64.lua', 'dis_arm.lua', 'dis_ppc.lua', 'dis_mips.lua', 'dis_mipsel.lua', 'bcsave.lua'] 2 | 3 | if get_option('app') 4 | install_data(jitlib_files, install_dir: jitlib_install_dir) 5 | endif 6 | -------------------------------------------------------------------------------- /src/jit/v.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------- 2 | -- Verbose mode of the LuaJIT compiler. 3 | -- 4 | -- Copyright (C) 2005-2022 Mike Pall. All rights reserved. 5 | -- Released under the MIT license. See Copyright Notice in luajit.h 6 | ---------------------------------------------------------------------------- 7 | -- 8 | -- This module shows verbose information about the progress of the 9 | -- JIT compiler. It prints one line for each generated trace. This module 10 | -- is useful to see which code has been compiled or where the compiler 11 | -- punts and falls back to the interpreter. 12 | -- 13 | -- Example usage: 14 | -- 15 | -- luajit -jv -e "for i=1,1000 do for j=1,1000 do end end" 16 | -- luajit -jv=myapp.out myapp.lua 17 | -- 18 | -- Default output is to stderr. To redirect the output to a file, pass a 19 | -- filename as an argument (use '-' for stdout) or set the environment 20 | -- variable LUAJIT_VERBOSEFILE. The file is overwritten every time the 21 | -- module is started. 22 | -- 23 | -- The output from the first example should look like this: 24 | -- 25 | -- [TRACE 1 (command line):1 loop] 26 | -- [TRACE 2 (1/3) (command line):1 -> 1] 27 | -- 28 | -- The first number in each line is the internal trace number. Next are 29 | -- the file name ('(command line)') and the line number (':1') where the 30 | -- trace has started. Side traces also show the parent trace number and 31 | -- the exit number where they are attached to in parentheses ('(1/3)'). 32 | -- An arrow at the end shows where the trace links to ('-> 1'), unless 33 | -- it loops to itself. 34 | -- 35 | -- In this case the inner loop gets hot and is traced first, generating 36 | -- a root trace. Then the last exit from the 1st trace gets hot, too, 37 | -- and triggers generation of the 2nd trace. The side trace follows the 38 | -- path along the outer loop and *around* the inner loop, back to its 39 | -- start, and then links to the 1st trace. Yes, this may seem unusual, 40 | -- if you know how traditional compilers work. Trace compilers are full 41 | -- of surprises like this -- have fun! :-) 42 | -- 43 | -- Aborted traces are shown like this: 44 | -- 45 | -- [TRACE --- foo.lua:44 -- leaving loop in root trace at foo:lua:50] 46 | -- 47 | -- Don't worry -- trace aborts are quite common, even in programs which 48 | -- can be fully compiled. The compiler may retry several times until it 49 | -- finds a suitable trace. 50 | -- 51 | -- Of course this doesn't work with features that are not-yet-implemented 52 | -- (NYI error messages). The VM simply falls back to the interpreter. This 53 | -- may not matter at all if the particular trace is not very high up in 54 | -- the CPU usage profile. Oh, and the interpreter is quite fast, too. 55 | -- 56 | -- Also check out the -jdump module, which prints all the gory details. 57 | -- 58 | ------------------------------------------------------------------------------ 59 | 60 | -- Cache some library functions and objects. 61 | local jit = require("jit") 62 | assert(jit.version_num == 20005, "LuaJIT core/library version mismatch") 63 | local jutil = require("jit.util") 64 | local vmdef = require("jit.vmdef") 65 | local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo 66 | local type, format = type, string.format 67 | local stdout, stderr = io.stdout, io.stderr 68 | 69 | -- Active flag and output file handle. 70 | local active, out 71 | 72 | ------------------------------------------------------------------------------ 73 | 74 | local startloc, startex 75 | 76 | local function fmtfunc(func, pc) 77 | local fi = funcinfo(func, pc) 78 | if fi.loc then 79 | return fi.loc 80 | elseif fi.ffid then 81 | return vmdef.ffnames[fi.ffid] 82 | elseif fi.addr then 83 | return format("C:%x", fi.addr) 84 | else 85 | return "(?)" 86 | end 87 | end 88 | 89 | -- Format trace error message. 90 | local function fmterr(err, info) 91 | if type(err) == "number" then 92 | if type(info) == "function" then info = fmtfunc(info) end 93 | err = format(vmdef.traceerr[err], info) 94 | end 95 | return err 96 | end 97 | 98 | -- Dump trace states. 99 | local function dump_trace(what, tr, func, pc, otr, oex) 100 | if what == "start" then 101 | startloc = fmtfunc(func, pc) 102 | startex = otr and "("..otr.."/"..oex..") " or "" 103 | else 104 | if what == "abort" then 105 | local loc = fmtfunc(func, pc) 106 | if loc ~= startloc then 107 | out:write(format("[TRACE --- %s%s -- %s at %s]\n", 108 | startex, startloc, fmterr(otr, oex), loc)) 109 | else 110 | out:write(format("[TRACE --- %s%s -- %s]\n", 111 | startex, startloc, fmterr(otr, oex))) 112 | end 113 | elseif what == "stop" then 114 | local info = traceinfo(tr) 115 | local link, ltype = info.link, info.linktype 116 | if ltype == "interpreter" then 117 | out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n", 118 | tr, startex, startloc)) 119 | elseif link == tr or link == 0 then 120 | out:write(format("[TRACE %3s %s%s %s]\n", 121 | tr, startex, startloc, ltype)) 122 | elseif ltype == "root" then 123 | out:write(format("[TRACE %3s %s%s -> %d]\n", 124 | tr, startex, startloc, link)) 125 | else 126 | out:write(format("[TRACE %3s %s%s -> %d %s]\n", 127 | tr, startex, startloc, link, ltype)) 128 | end 129 | else 130 | out:write(format("[TRACE %s]\n", what)) 131 | end 132 | out:flush() 133 | end 134 | end 135 | 136 | ------------------------------------------------------------------------------ 137 | 138 | -- Detach dump handlers. 139 | local function dumpoff() 140 | if active then 141 | active = false 142 | jit.attach(dump_trace) 143 | if out and out ~= stdout and out ~= stderr then out:close() end 144 | out = nil 145 | end 146 | end 147 | 148 | -- Open the output file and attach dump handlers. 149 | local function dumpon(outfile) 150 | if active then dumpoff() end 151 | if not outfile then outfile = os.getenv("LUAJIT_VERBOSEFILE") end 152 | if outfile then 153 | out = outfile == "-" and stdout or assert(io.open(outfile, "w")) 154 | else 155 | out = stderr 156 | end 157 | jit.attach(dump_trace, "trace") 158 | active = true 159 | end 160 | 161 | -- Public module functions. 162 | module(...) 163 | 164 | on = dumpon 165 | off = dumpoff 166 | start = dumpon -- For -j command line option. 167 | 168 | -------------------------------------------------------------------------------- /src/lauxlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Auxiliary functions for building Lua libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lauxlib_h 9 | #define lauxlib_h 10 | 11 | 12 | #include 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | 18 | #define luaL_getn(L,i) ((int)lua_objlen(L, i)) 19 | #define luaL_setn(L,i,j) ((void)0) /* no op! */ 20 | 21 | /* extra error code for `luaL_load' */ 22 | #define LUA_ERRFILE (LUA_ERRERR+1) 23 | 24 | typedef struct luaL_Reg { 25 | const char *name; 26 | lua_CFunction func; 27 | } luaL_Reg; 28 | 29 | LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, 30 | const luaL_Reg *l, int nup); 31 | LUALIB_API void (luaL_register) (lua_State *L, const char *libname, 32 | const luaL_Reg *l); 33 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); 34 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 35 | LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); 36 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); 37 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, 38 | size_t *l); 39 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, 40 | const char *def, size_t *l); 41 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); 42 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); 43 | 44 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); 45 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, 46 | lua_Integer def); 47 | 48 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); 49 | LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); 50 | LUALIB_API void (luaL_checkany) (lua_State *L, int narg); 51 | 52 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); 53 | LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); 54 | 55 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); 56 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); 57 | 58 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, 59 | const char *const lst[]); 60 | 61 | LUALIB_API int (luaL_ref) (lua_State *L, int t); 62 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 63 | 64 | LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); 65 | LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, 66 | const char *name); 67 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 68 | 69 | LUALIB_API lua_State *(luaL_newstate) (void); 70 | 71 | 72 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, 73 | const char *r); 74 | 75 | LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, 76 | const char *fname, int szhint); 77 | 78 | /* From Lua 5.2. */ 79 | LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname); 80 | LUALIB_API int luaL_execresult(lua_State *L, int stat); 81 | LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, 82 | const char *mode); 83 | LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, 84 | const char *name, const char *mode); 85 | LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg, 86 | int level); 87 | 88 | 89 | /* 90 | ** =============================================================== 91 | ** some useful macros 92 | ** =============================================================== 93 | */ 94 | 95 | #define luaL_argcheck(L, cond,numarg,extramsg) \ 96 | ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) 97 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 98 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) 99 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) 100 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) 101 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) 102 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) 103 | 104 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) 105 | 106 | #define luaL_dofile(L, fn) \ 107 | (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) 108 | 109 | #define luaL_dostring(L, s) \ 110 | (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) 111 | 112 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) 113 | 114 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) 115 | 116 | /* 117 | ** {====================================================== 118 | ** Generic Buffer manipulation 119 | ** ======================================================= 120 | */ 121 | 122 | 123 | 124 | typedef struct luaL_Buffer { 125 | char *p; /* current position in buffer */ 126 | int lvl; /* number of strings in the stack (level) */ 127 | lua_State *L; 128 | char buffer[LUAL_BUFFERSIZE]; 129 | } luaL_Buffer; 130 | 131 | #define luaL_addchar(B,c) \ 132 | ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ 133 | (*(B)->p++ = (char)(c))) 134 | 135 | /* compatibility only */ 136 | #define luaL_putchar(B,c) luaL_addchar(B,c) 137 | 138 | #define luaL_addsize(B,n) ((B)->p += (n)) 139 | 140 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); 141 | LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); 142 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); 143 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); 144 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); 145 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); 146 | 147 | 148 | /* }====================================================== */ 149 | 150 | 151 | /* compatibility with ref system */ 152 | 153 | /* pre-defined references */ 154 | #define LUA_NOREF (-2) 155 | #define LUA_REFNIL (-1) 156 | 157 | #define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ 158 | (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) 159 | 160 | #define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) 161 | 162 | #define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) 163 | 164 | 165 | #define luaL_reg luaL_Reg 166 | 167 | #endif 168 | -------------------------------------------------------------------------------- /src/lib_bit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** Bit manipulation library. 3 | ** Copyright (C) 2005-2022 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_str.h" 16 | #include "lj_lib.h" 17 | 18 | /* ------------------------------------------------------------------------ */ 19 | 20 | #define LJLIB_MODULE_bit 21 | 22 | LJLIB_ASM(bit_tobit) LJLIB_REC(bit_unary IR_TOBIT) 23 | { 24 | lj_lib_checknumber(L, 1); 25 | return FFH_RETRY; 26 | } 27 | LJLIB_ASM_(bit_bnot) LJLIB_REC(bit_unary IR_BNOT) 28 | LJLIB_ASM_(bit_bswap) LJLIB_REC(bit_unary IR_BSWAP) 29 | 30 | LJLIB_ASM(bit_lshift) LJLIB_REC(bit_shift IR_BSHL) 31 | { 32 | lj_lib_checknumber(L, 1); 33 | lj_lib_checkbit(L, 2); 34 | return FFH_RETRY; 35 | } 36 | LJLIB_ASM_(bit_rshift) LJLIB_REC(bit_shift IR_BSHR) 37 | LJLIB_ASM_(bit_arshift) LJLIB_REC(bit_shift IR_BSAR) 38 | LJLIB_ASM_(bit_rol) LJLIB_REC(bit_shift IR_BROL) 39 | LJLIB_ASM_(bit_ror) LJLIB_REC(bit_shift IR_BROR) 40 | 41 | LJLIB_ASM(bit_band) LJLIB_REC(bit_nary IR_BAND) 42 | { 43 | int i = 0; 44 | do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top); 45 | return FFH_RETRY; 46 | } 47 | LJLIB_ASM_(bit_bor) LJLIB_REC(bit_nary IR_BOR) 48 | LJLIB_ASM_(bit_bxor) LJLIB_REC(bit_nary IR_BXOR) 49 | 50 | /* ------------------------------------------------------------------------ */ 51 | 52 | LJLIB_CF(bit_tohex) 53 | { 54 | uint32_t b = (uint32_t)lj_lib_checkbit(L, 1); 55 | int32_t i, n = L->base+1 >= L->top ? 8 : lj_lib_checkbit(L, 2); 56 | const char *hexdigits = "0123456789abcdef"; 57 | char buf[8]; 58 | if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; } 59 | if (n > 8) n = 8; 60 | for (i = n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; } 61 | lua_pushlstring(L, buf, (size_t)n); 62 | return 1; 63 | } 64 | 65 | /* ------------------------------------------------------------------------ */ 66 | 67 | #include "lj_libdef.h" 68 | 69 | LUALIB_API int luaopen_bit(lua_State *L) 70 | { 71 | LJ_LIB_REG(L, LUA_BITLIBNAME, bit); 72 | return 1; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /src/lib_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** Library initialization. 3 | ** Copyright (C) 2005-2022 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.supp: -------------------------------------------------------------------------------- 1 | # Valgrind suppression file for LuaJIT 2.0. 2 | { 3 | Optimized string compare 4 | Memcheck:Addr4 5 | fun:lj_str_cmp 6 | } 7 | { 8 | Optimized string compare 9 | Memcheck:Addr1 10 | fun:lj_str_cmp 11 | } 12 | { 13 | Optimized string compare 14 | Memcheck:Addr4 15 | fun:lj_str_new 16 | } 17 | { 18 | Optimized string compare 19 | Memcheck:Addr1 20 | fun:lj_str_new 21 | } 22 | { 23 | Optimized string compare 24 | Memcheck:Cond 25 | fun:lj_str_new 26 | } 27 | { 28 | Optimized string compare 29 | Memcheck:Addr4 30 | fun:str_fastcmp 31 | } 32 | { 33 | Optimized string compare 34 | Memcheck:Addr1 35 | fun:str_fastcmp 36 | } 37 | { 38 | Optimized string compare 39 | Memcheck:Cond 40 | fun:str_fastcmp 41 | } 42 | -------------------------------------------------------------------------------- /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(void); 13 | LJ_FUNC void lj_alloc_destroy(void *msp); 14 | LJ_FUNC void *lj_alloc_f(void *msp, void *ptr, size_t osize, size_t nsize); 15 | #endif 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/lj_arch_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "lj_arch.h" 3 | 4 | /* Print in stdout the following string: 5 | 6 | ::: 7 | 8 | Where are comma separated strings. 9 | 10 | Each value correspond to the variable of the same name in Luajit's 11 | original Makefile. 12 | */ 13 | 14 | /* NB This file is intentionally primitive and no dynamic memory is used. 15 | It is not supposed to be a good, general purpose, programming style 16 | but it is good enough to print some architecture details. */ 17 | 18 | #define MAIN_SEPARATOR ":" 19 | #define DEFS_SEPARATOR "," 20 | 21 | static void add_def(const char *args[], int *args_n, const char *def) { 22 | const int n = *args_n; 23 | args[n] = "-D"; 24 | args[n + 1] = def; 25 | *args_n = n + 2; 26 | } 27 | 28 | int main() { 29 | const char *lj_arch, *lj_os, *dasm_arch; 30 | const char *arch_defs[16]; 31 | int arch_defs_n = 0; 32 | const char *x_arch_option = NULL; 33 | 34 | #ifdef LJ_TARGET_X64 35 | lj_arch = "x64"; 36 | #elif LJ_TARGET_X86 37 | lj_arch = "x86"; 38 | #elif LJ_TARGET_ARM 39 | lj_arch = "arm"; 40 | #elif LJ_TARGET_PPC 41 | lj_arch = "ppc"; 42 | #elif LJ_TARGET_PPCSPE 43 | lj_arch = "ppcspe"; 44 | #elif LJ_TARGET_MIPS 45 | lj_arch = "mips"; 46 | #ifdef MIPSEL 47 | x_arch_option = "-D__MIPSEL__=1"; 48 | #endif 49 | #else 50 | fprintf(stderr, "Unsupported architecture\n"); 51 | exit(1); 52 | #endif 53 | 54 | char luajit_target_def[128]; 55 | sprintf(luajit_target_def, "-DLUAJIT_TARGET=LUAJIT_ARCH_%s", lj_arch); 56 | arch_defs[arch_defs_n++] = luajit_target_def; 57 | 58 | if (x_arch_option) { 59 | arch_defs[arch_defs_n++] = x_arch_option; 60 | } 61 | 62 | #if LUAJIT_OS == LUAJIT_OS_OTHER 63 | lj_os = "OTHER"; 64 | #elif LUAJIT_OS == LUAJIT_OS_WINDOWS 65 | lj_os = "WINDOWS"; 66 | #elif LUAJIT_OS == LUAJIT_OS_LINUX 67 | lj_os = "LINUX"; 68 | #elif LUAJIT_OS == LUAJIT_OS_OSX 69 | lj_os = "OSX"; 70 | #elif LUAJIT_OS == LUAJIT_OS_BSD 71 | lj_os = "BSD"; 72 | #elif LUAJIT_OS == LUAJIT_OS_POSIX 73 | lj_os = "POSIX"; 74 | #else 75 | fprintf(stderr, "Unsupported OS\n"); 76 | exit(1); 77 | #endif 78 | 79 | char luajit_os_def[128]; 80 | sprintf(luajit_os_def, "-DLUAJIT_OS=LUAJIT_OS_%s", lj_os); 81 | arch_defs[arch_defs_n++] = luajit_os_def; 82 | 83 | #ifdef LJ_TARGET_X64 84 | dasm_arch = "x86"; 85 | #else 86 | dasm_arch = lj_arch; 87 | #endif 88 | 89 | const char *dasm[32]; 90 | int dasm_n = 0; 91 | 92 | #if LJ_ARCH_BITS == 64 93 | add_def(dasm, &dasm_n, "P64"); 94 | #endif 95 | #if LJ_HASJIT == 1 96 | add_def(dasm, &dasm_n, "JIT"); 97 | #endif 98 | #if LJ_HASFFI == 1 99 | add_def(dasm, &dasm_n, "FFI"); 100 | #endif 101 | #if LJ_DUALNUM == 1 102 | add_def(dasm, &dasm_n, "DUALNUM"); 103 | #endif 104 | #if LJ_ARCH_HASFPU == 1 105 | add_def(dasm, &dasm_n, "FPU"); 106 | arch_defs[arch_defs_n++] = "-DLJ_ARCH_HASFPU=1"; 107 | #else 108 | arch_defs[arch_defs_n++] = "-DLJ_ARCH_HASFPU=0"; 109 | #endif 110 | #if LJ_ABI_SOFTFP == 1 111 | arch_defs[arch_defs_n++] = "-DLJ_ABI_SOFTFP=1"; 112 | #else 113 | add_def(dasm, &dasm_n, "HFABI"); 114 | arch_defs[arch_defs_n++] = "-DLJ_ABI_SOFTFP=0"; 115 | #endif 116 | #if LJ_NO_UNWIND == 1 117 | add_def(dasm, &dasm_n, "NO_UNWIND"); 118 | arch_defs[arch_defs_n++] = "-DLUAJIT_NO_UNWIND"; 119 | #endif 120 | 121 | char arm_arch_version[16]; 122 | #if LJ_ARCH_VERSION 123 | sprintf(arm_arch_version, "VER=%d", LJ_ARCH_VERSION); 124 | #else 125 | sprintf(arm_arch_version, "VER="); 126 | #endif 127 | add_def(dasm, &dasm_n, arm_arch_version); 128 | 129 | #ifdef _WIN32 130 | add_def(dasm, &dasm_n, "WIN"); 131 | #endif 132 | 133 | #if (!defined LJ_TARGET_X64 && defined LJ_TARGET_X86) && __SSE2__ == 1 134 | add_def(dasm, &dasm_n, "SSE"); 135 | #endif 136 | 137 | printf("%s%s%s%s", lj_arch, MAIN_SEPARATOR, dasm_arch, MAIN_SEPARATOR); 138 | for (int i = 0; i < arch_defs_n; i++) { 139 | printf("%s%s", i > 0 ? DEFS_SEPARATOR : "", arch_defs[i]); 140 | } 141 | printf("%s", MAIN_SEPARATOR); 142 | for (int i = 0; i < dasm_n; i++) { 143 | printf("%s%s", i > 0 ? DEFS_SEPARATOR : "", dasm[i]); 144 | } 145 | 146 | return 0; 147 | } 148 | -------------------------------------------------------------------------------- /src/lj_asm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** IR assembler (SSA IR -> machine code). 3 | ** Copyright (C) 2005-2022 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_bc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** Bytecode instruction modes. 3 | ** Copyright (C) 2005-2022 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-2022 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 1 40 | 41 | /* Compatibility flags. */ 42 | #define BCDUMP_F_BE 0x01 43 | #define BCDUMP_F_STRIP 0x02 44 | #define BCDUMP_F_FFI 0x04 45 | 46 | #define BCDUMP_F_KNOWN (BCDUMP_F_FFI*2-1) 47 | 48 | /* Type codes for the GC constants of a prototype. Plus length for strings. */ 49 | enum { 50 | BCDUMP_KGC_CHILD, BCDUMP_KGC_TAB, BCDUMP_KGC_I64, BCDUMP_KGC_U64, 51 | BCDUMP_KGC_COMPLEX, BCDUMP_KGC_STR 52 | }; 53 | 54 | /* Type codes for the keys/values of a constant table. */ 55 | enum { 56 | BCDUMP_KTAB_NIL, BCDUMP_KTAB_FALSE, BCDUMP_KTAB_TRUE, 57 | BCDUMP_KTAB_INT, BCDUMP_KTAB_NUM, BCDUMP_KTAB_STR 58 | }; 59 | 60 | /* -- Bytecode reader/writer ---------------------------------------------- */ 61 | 62 | LJ_FUNC int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer, 63 | void *data, int strip); 64 | LJ_FUNC GCproto *lj_bcread(LexState *ls); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/lj_carith.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** C data arithmetic. 3 | ** Copyright (C) 2005-2022 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 && LJ_HASJIT 16 | LJ_FUNC int64_t lj_carith_mul64(int64_t x, int64_t k); 17 | #endif 18 | LJ_FUNC uint64_t lj_carith_divu64(uint64_t a, uint64_t b); 19 | LJ_FUNC int64_t lj_carith_divi64(int64_t a, int64_t b); 20 | LJ_FUNC uint64_t lj_carith_modu64(uint64_t a, uint64_t b); 21 | LJ_FUNC int64_t lj_carith_modi64(int64_t a, int64_t b); 22 | LJ_FUNC uint64_t lj_carith_powu64(uint64_t x, uint64_t k); 23 | LJ_FUNC int64_t lj_carith_powi64(int64_t x, int64_t k); 24 | 25 | #endif 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/lj_ccall.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** FFI C call handling. 3 | ** Copyright (C) 2005-2022 Mike Pall. See Copyright Notice in luajit.h 4 | */ 5 | 6 | #ifndef _LJ_CCALL_H 7 | #define _LJ_CCALL_H 8 | 9 | #include "lj_obj.h" 10 | #include "lj_ctype.h" 11 | 12 | #if LJ_HASFFI 13 | 14 | /* -- C calling conventions ----------------------------------------------- */ 15 | 16 | #if LJ_TARGET_X86ORX64 17 | 18 | #if LJ_TARGET_X86 19 | #define CCALL_NARG_GPR 2 /* For fastcall arguments. */ 20 | #define CCALL_NARG_FPR 0 21 | #define CCALL_NRET_GPR 2 22 | #define CCALL_NRET_FPR 1 /* For FP results on x87 stack. */ 23 | #define CCALL_ALIGN_STACKARG 0 /* Don't align argument on stack. */ 24 | #elif LJ_ABI_WIN 25 | #define CCALL_NARG_GPR 4 26 | #define CCALL_NARG_FPR 4 27 | #define CCALL_NRET_GPR 1 28 | #define CCALL_NRET_FPR 1 29 | #define CCALL_SPS_EXTRA 4 30 | #else 31 | #define CCALL_NARG_GPR 6 32 | #define CCALL_NARG_FPR 8 33 | #define CCALL_NRET_GPR 2 34 | #define CCALL_NRET_FPR 2 35 | #define CCALL_VECTOR_REG 1 /* Pass vectors in registers. */ 36 | #endif 37 | 38 | #define CCALL_SPS_FREE 1 39 | #define CCALL_ALIGN_CALLSTATE 16 40 | 41 | typedef LJ_ALIGN(16) union FPRArg { 42 | double d[2]; 43 | float f[4]; 44 | uint8_t b[16]; 45 | uint16_t s[8]; 46 | int i[4]; 47 | int64_t l[2]; 48 | } FPRArg; 49 | 50 | typedef intptr_t GPRArg; 51 | 52 | #elif LJ_TARGET_ARM 53 | 54 | #define CCALL_NARG_GPR 4 55 | #define CCALL_NRET_GPR 2 /* For softfp double. */ 56 | #if LJ_ABI_SOFTFP 57 | #define CCALL_NARG_FPR 0 58 | #define CCALL_NRET_FPR 0 59 | #else 60 | #define CCALL_NARG_FPR 8 61 | #define CCALL_NRET_FPR 4 62 | #endif 63 | #define CCALL_SPS_FREE 0 64 | 65 | typedef intptr_t GPRArg; 66 | typedef union FPRArg { 67 | double d; 68 | float f[2]; 69 | } FPRArg; 70 | 71 | #elif LJ_TARGET_PPC 72 | 73 | #define CCALL_NARG_GPR 8 74 | #define CCALL_NARG_FPR 8 75 | #define CCALL_NRET_GPR 4 /* For complex double. */ 76 | #define CCALL_NRET_FPR 1 77 | #define CCALL_SPS_EXTRA 4 78 | #define CCALL_SPS_FREE 0 79 | 80 | typedef intptr_t GPRArg; 81 | typedef double FPRArg; 82 | 83 | #elif LJ_TARGET_PPCSPE 84 | 85 | #define CCALL_NARG_GPR 8 86 | #define CCALL_NARG_FPR 0 87 | #define CCALL_NRET_GPR 4 /* For softfp complex double. */ 88 | #define CCALL_NRET_FPR 0 89 | #define CCALL_SPS_FREE 0 /* NYI */ 90 | 91 | typedef intptr_t GPRArg; 92 | 93 | #elif LJ_TARGET_MIPS 94 | 95 | #define CCALL_NARG_GPR 4 96 | #define CCALL_NARG_FPR 2 97 | #define CCALL_NRET_GPR 2 98 | #define CCALL_NRET_FPR 2 99 | #define CCALL_SPS_EXTRA 7 100 | #define CCALL_SPS_FREE 1 101 | 102 | typedef intptr_t GPRArg; 103 | typedef union FPRArg { 104 | double d; 105 | struct { LJ_ENDIAN_LOHI(float f; , float g;) }; 106 | } FPRArg; 107 | 108 | #else 109 | #error "Missing calling convention definitions for this architecture" 110 | #endif 111 | 112 | #ifndef CCALL_SPS_EXTRA 113 | #define CCALL_SPS_EXTRA 0 114 | #endif 115 | #ifndef CCALL_VECTOR_REG 116 | #define CCALL_VECTOR_REG 0 117 | #endif 118 | #ifndef CCALL_ALIGN_STACKARG 119 | #define CCALL_ALIGN_STACKARG 1 120 | #endif 121 | #ifndef CCALL_ALIGN_CALLSTATE 122 | #define CCALL_ALIGN_CALLSTATE 8 123 | #endif 124 | 125 | #define CCALL_NUM_GPR \ 126 | (CCALL_NARG_GPR > CCALL_NRET_GPR ? CCALL_NARG_GPR : CCALL_NRET_GPR) 127 | #define CCALL_NUM_FPR \ 128 | (CCALL_NARG_FPR > CCALL_NRET_FPR ? CCALL_NARG_FPR : CCALL_NRET_FPR) 129 | 130 | /* Check against constants in lj_ctype.h. */ 131 | LJ_STATIC_ASSERT(CCALL_NUM_GPR <= CCALL_MAX_GPR); 132 | LJ_STATIC_ASSERT(CCALL_NUM_FPR <= CCALL_MAX_FPR); 133 | 134 | #define CCALL_MAXSTACK 32 135 | 136 | /* -- C call state -------------------------------------------------------- */ 137 | 138 | typedef LJ_ALIGN(CCALL_ALIGN_CALLSTATE) struct CCallState { 139 | void (*func)(void); /* Pointer to called function. */ 140 | uint32_t spadj; /* Stack pointer adjustment. */ 141 | uint8_t nsp; /* Number of stack slots. */ 142 | uint8_t retref; /* Return value by reference. */ 143 | #if LJ_TARGET_X64 144 | uint8_t ngpr; /* Number of arguments in GPRs. */ 145 | uint8_t nfpr; /* Number of arguments in FPRs. */ 146 | #elif LJ_TARGET_X86 147 | uint8_t resx87; /* Result on x87 stack: 1:float, 2:double. */ 148 | #elif LJ_TARGET_PPC 149 | uint8_t nfpr; /* Number of arguments in FPRs. */ 150 | #endif 151 | #if LJ_32 152 | int32_t align1; 153 | #endif 154 | #if CCALL_NUM_FPR 155 | FPRArg fpr[CCALL_NUM_FPR]; /* Arguments/results in FPRs. */ 156 | #endif 157 | GPRArg gpr[CCALL_NUM_GPR]; /* Arguments/results in GPRs. */ 158 | GPRArg stack[CCALL_MAXSTACK]; /* Stack slots. */ 159 | } CCallState; 160 | 161 | /* -- C call handling ----------------------------------------------------- */ 162 | 163 | /* Really belongs to lj_vm.h. */ 164 | LJ_ASMF void LJ_FASTCALL lj_vm_ffi_call(CCallState *cc); 165 | 166 | LJ_FUNC CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o); 167 | LJ_FUNC int lj_ccall_func(lua_State *L, GCcdata *cd); 168 | 169 | #endif 170 | 171 | #endif 172 | -------------------------------------------------------------------------------- /src/lj_ccallback.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** FFI C callback handling. 3 | ** Copyright (C) 2005-2022 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-2022 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 | lua_assert(ctype_type(info) <= CT_MAYCONVERT); 31 | #if LJ_64 32 | idx = ((uint32_t)(U64x(f436fff5,fff7f021) >> 4*idx) & 15u); 33 | #else 34 | idx = (((idx < 8 ? 0xfff7f021u : 0xf436fff5) >> 4*(idx & 7u)) & 15u); 35 | #endif 36 | lua_assert(idx < 8); 37 | return idx; 38 | } 39 | 40 | #define cconv_idx2(dinfo, sinfo) \ 41 | ((cconv_idx((dinfo)) << 3) + cconv_idx((sinfo))) 42 | 43 | #define CCX(dst, src) ((CCX_##dst << 3) + CCX_##src) 44 | 45 | /* Conversion flags. */ 46 | #define CCF_CAST 0x00000001u 47 | #define CCF_FROMTV 0x00000002u 48 | #define CCF_SAME 0x00000004u 49 | #define CCF_IGNQUAL 0x00000008u 50 | 51 | #define CCF_ARG_SHIFT 8 52 | #define CCF_ARG(n) ((n) << CCF_ARG_SHIFT) 53 | #define CCF_GETARG(f) ((f) >> CCF_ARG_SHIFT) 54 | 55 | LJ_FUNC int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags); 56 | LJ_FUNC void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s, 57 | uint8_t *dp, uint8_t *sp, CTInfo flags); 58 | LJ_FUNC int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, 59 | TValue *o, uint8_t *sp); 60 | LJ_FUNC int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp); 61 | LJ_FUNC void lj_cconv_ct_tv(CTState *cts, CType *d, 62 | uint8_t *dp, TValue *o, CTInfo flags); 63 | LJ_FUNC void lj_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o); 64 | LJ_FUNC int lj_cconv_multi_init(CTState *cts, CType *d, TValue *o); 65 | LJ_FUNC void lj_cconv_ct_init(CTState *cts, CType *d, CTSize sz, 66 | uint8_t *dp, TValue *o, MSize len); 67 | 68 | #endif 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/lj_cdata.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** C data management. 3 | ** Copyright (C) 2005-2022 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 | lua_assert(sz == CTSIZE_PTR); 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 | lua_assert(sz == CTSIZE_PTR); 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 | lua_assert((ctype_hassize(ct->info) ? ct->size : CTSIZE_PTR) == sz); 44 | #endif 45 | cd = (GCcdata *)lj_mem_newgco(cts->L, sizeof(GCcdata) + sz); 46 | cd->gct = ~LJ_TCDATA; 47 | cd->ctypeid = ctype_check(cts, id); 48 | return cd; 49 | } 50 | 51 | /* Variant which works without a valid CTState. */ 52 | static LJ_AINLINE GCcdata *lj_cdata_new_(lua_State *L, CTypeID id, CTSize sz) 53 | { 54 | GCcdata *cd = (GCcdata *)lj_mem_newgco(L, sizeof(GCcdata) + sz); 55 | cd->gct = ~LJ_TCDATA; 56 | cd->ctypeid = id; 57 | return cd; 58 | } 59 | 60 | LJ_FUNC GCcdata *lj_cdata_newref(CTState *cts, const void *pp, CTypeID id); 61 | LJ_FUNC GCcdata *lj_cdata_newv(CTState *cts, CTypeID id, CTSize sz, 62 | CTSize align); 63 | 64 | LJ_FUNC void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd); 65 | LJ_FUNCA TValue * LJ_FASTCALL lj_cdata_setfin(lua_State *L, GCcdata *cd); 66 | 67 | LJ_FUNC CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, 68 | uint8_t **pp, CTInfo *qual); 69 | LJ_FUNC int lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp); 70 | LJ_FUNC void lj_cdata_set(CTState *cts, CType *d, uint8_t *dp, TValue *o, 71 | CTInfo qual); 72 | 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /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-2022 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-2022 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 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/lj_crecord.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Trace recorder for C data operations. 3 | ** Copyright (C) 2005-2022 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 | LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/lj_debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Debugging and introspection. 3 | ** Copyright (C) 2005-2022 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 cTValue *lj_debug_frame(lua_State *L, int level, int *size); 30 | LJ_FUNC BCLine LJ_FASTCALL lj_debug_line(GCproto *pt, BCPos pc); 31 | LJ_FUNC const char *lj_debug_uvname(GCproto *pt, uint32_t idx); 32 | LJ_FUNC const char *lj_debug_uvnamev(cTValue *o, uint32_t idx, TValue **tvp, 33 | GCobj **op); 34 | LJ_FUNC const char *lj_debug_slotname(GCproto *pt, const BCIns *pc, 35 | BCReg slot, const char **name); 36 | LJ_FUNC const char *lj_debug_funcname(lua_State *L, TValue *frame, 37 | const char **name); 38 | LJ_FUNC void lj_debug_shortname(char *out, GCstr *str); 39 | LJ_FUNC void lj_debug_addloc(lua_State *L, const char *msg, 40 | cTValue *frame, cTValue *nextframe); 41 | LJ_FUNC void lj_debug_pushloc(lua_State *L, GCproto *pt, BCPos pc); 42 | LJ_FUNC int lj_debug_getinfo(lua_State *L, const char *what, lj_Debug *ar, 43 | int ext); 44 | 45 | /* Fixed internal variable names. */ 46 | #define VARNAMEDEF(_) \ 47 | _(FOR_IDX, "(for index)") \ 48 | _(FOR_STOP, "(for limit)") \ 49 | _(FOR_STEP, "(for step)") \ 50 | _(FOR_GEN, "(for generator)") \ 51 | _(FOR_STATE, "(for state)") \ 52 | _(FOR_CTL, "(for control)") 53 | 54 | enum { 55 | VARNAME_END, 56 | #define VARNAMEENUM(name, str) VARNAME_##name, 57 | VARNAMEDEF(VARNAMEENUM) 58 | #undef VARNAMEENUM 59 | VARNAME__MAX 60 | }; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/lj_dispatch.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Instruction dispatch handling. 3 | ** Copyright (C) 2005-2022 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 | #if LJ_HASJIT 18 | #define JITGOTDEF(_) _(lj_trace_exit) _(lj_trace_hot) 19 | #else 20 | #define JITGOTDEF(_) 21 | #endif 22 | #if LJ_HASFFI 23 | #define FFIGOTDEF(_) \ 24 | _(lj_meta_equal_cd) _(lj_ccallback_enter) _(lj_ccallback_leave) 25 | #else 26 | #define FFIGOTDEF(_) 27 | #endif 28 | #define GOTDEF(_) \ 29 | _(floor) _(ceil) _(trunc) _(log) _(log10) _(exp) _(sin) _(cos) _(tan) \ 30 | _(asin) _(acos) _(atan) _(sinh) _(cosh) _(tanh) _(frexp) _(modf) _(atan2) \ 31 | _(pow) _(fmod) _(ldexp) \ 32 | _(lj_dispatch_call) _(lj_dispatch_ins) _(lj_err_throw) _(lj_err_run) \ 33 | _(lj_ffh_coroutine_wrap_err) _(lj_func_closeuv) _(lj_func_newL_gc) \ 34 | _(lj_gc_barrieruv) _(lj_gc_step) _(lj_gc_step_fixtop) _(lj_meta_arith) \ 35 | _(lj_meta_call) _(lj_meta_cat) _(lj_meta_comp) _(lj_meta_equal) \ 36 | _(lj_meta_for) _(lj_meta_len) _(lj_meta_tget) _(lj_meta_tset) \ 37 | _(lj_state_growstack) _(lj_str_fromnum) _(lj_str_fromnumber) _(lj_str_new) \ 38 | _(lj_tab_dup) _(lj_tab_get) _(lj_tab_getinth) _(lj_tab_len) _(lj_tab_new) \ 39 | _(lj_tab_newkey) _(lj_tab_next) _(lj_tab_reasize) \ 40 | JITGOTDEF(_) FFIGOTDEF(_) 41 | 42 | enum { 43 | #define GOTENUM(name) LJ_GOT_##name, 44 | GOTDEF(GOTENUM) 45 | #undef GOTENUM 46 | LJ_GOT__MAX 47 | }; 48 | #endif 49 | 50 | /* Type of hot counter. Must match the code in the assembler VM. */ 51 | /* 16 bits are sufficient. Only 0.0015% overhead with maximum slot penalty. */ 52 | typedef uint16_t HotCount; 53 | 54 | /* Number of hot counter hash table entries (must be a power of two). */ 55 | #define HOTCOUNT_SIZE 64 56 | #define HOTCOUNT_PCMASK ((HOTCOUNT_SIZE-1)*sizeof(HotCount)) 57 | 58 | /* Hotcount decrements. */ 59 | #define HOTCOUNT_LOOP 2 60 | #define HOTCOUNT_CALL 1 61 | 62 | /* This solves a circular dependency problem -- bump as needed. Sigh. */ 63 | #define GG_NUM_ASMFF 62 64 | 65 | #define GG_LEN_DDISP (BC__MAX + GG_NUM_ASMFF) 66 | #define GG_LEN_SDISP BC_FUNCF 67 | #define GG_LEN_DISP (GG_LEN_DDISP + GG_LEN_SDISP) 68 | 69 | /* Global state, main thread and extra fields are allocated together. */ 70 | typedef struct GG_State { 71 | lua_State L; /* Main thread. */ 72 | global_State g; /* Global state. */ 73 | #if LJ_TARGET_ARM 74 | /* Make g reachable via K12 encoded DISPATCH-relative addressing. */ 75 | uint8_t align1[(16-sizeof(global_State))&15]; 76 | #endif 77 | #if LJ_TARGET_MIPS 78 | ASMFunction got[LJ_GOT__MAX]; /* Global offset table. */ 79 | #endif 80 | #if LJ_HASJIT 81 | jit_State J; /* JIT state. */ 82 | HotCount hotcount[HOTCOUNT_SIZE]; /* Hot counters. */ 83 | #if LJ_TARGET_ARM 84 | /* Ditto for J. */ 85 | uint8_t align2[(16-sizeof(jit_State)-sizeof(HotCount)*HOTCOUNT_SIZE)&15]; 86 | #endif 87 | #endif 88 | ASMFunction dispatch[GG_LEN_DISP]; /* Instruction dispatch tables. */ 89 | BCIns bcff[GG_NUM_ASMFF]; /* Bytecode for ASM fast functions. */ 90 | } GG_State; 91 | 92 | #define GG_OFS(field) ((int)offsetof(GG_State, field)) 93 | #define G2GG(gl) ((GG_State *)((char *)(gl) - GG_OFS(g))) 94 | #define J2GG(j) ((GG_State *)((char *)(j) - GG_OFS(J))) 95 | #define L2GG(L) (G2GG(G(L))) 96 | #define J2G(J) (&J2GG(J)->g) 97 | #define G2J(gl) (&G2GG(gl)->J) 98 | #define L2J(L) (&L2GG(L)->J) 99 | #define GG_G2DISP (GG_OFS(dispatch) - GG_OFS(g)) 100 | #define GG_DISP2G (GG_OFS(g) - GG_OFS(dispatch)) 101 | #define GG_DISP2J (GG_OFS(J) - GG_OFS(dispatch)) 102 | #define GG_DISP2HOT (GG_OFS(hotcount) - GG_OFS(dispatch)) 103 | #define GG_DISP2STATIC (GG_LEN_DDISP*(int)sizeof(ASMFunction)) 104 | 105 | #define hotcount_get(gg, pc) \ 106 | (gg)->hotcount[(u32ptr(pc)>>2) & (HOTCOUNT_SIZE-1)] 107 | #define hotcount_set(gg, pc, val) \ 108 | (hotcount_get((gg), (pc)) = (HotCount)(val)) 109 | 110 | /* Dispatch table management. */ 111 | LJ_FUNC void lj_dispatch_init(GG_State *GG); 112 | #if LJ_HASJIT 113 | LJ_FUNC void lj_dispatch_init_hotcount(global_State *g); 114 | #endif 115 | LJ_FUNC void lj_dispatch_update(global_State *g); 116 | 117 | /* Instruction dispatch callback for hooks or when recording. */ 118 | LJ_FUNCA void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc); 119 | LJ_FUNCA ASMFunction LJ_FASTCALL lj_dispatch_call(lua_State *L, const BCIns*pc); 120 | LJ_FUNCA void LJ_FASTCALL lj_dispatch_return(lua_State *L, const BCIns *pc); 121 | 122 | #if LJ_HASFFI && !defined(_BUILDVM_H) 123 | /* Save/restore errno and GetLastError() around hooks, exits and recording. */ 124 | #include 125 | #if LJ_TARGET_WINDOWS 126 | #define WIN32_LEAN_AND_MEAN 127 | #include 128 | #define ERRNO_SAVE int olderr = errno; DWORD oldwerr = GetLastError(); 129 | #define ERRNO_RESTORE errno = olderr; SetLastError(oldwerr); 130 | #else 131 | #define ERRNO_SAVE int olderr = errno; 132 | #define ERRNO_RESTORE errno = olderr; 133 | #endif 134 | #else 135 | #define ERRNO_SAVE 136 | #define ERRNO_RESTORE 137 | #endif 138 | 139 | #endif 140 | -------------------------------------------------------------------------------- /src/lj_err.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Error handling. 3 | ** Copyright (C) 2005-2022 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_FUNCA_NORET void LJ_FASTCALL lj_err_run(lua_State *L); 27 | LJ_FUNC_NORET void lj_err_msg(lua_State *L, ErrMsg em); 28 | LJ_FUNC_NORET void lj_err_lex(lua_State *L, GCstr *src, const char *tok, 29 | BCLine line, ErrMsg em, va_list argp); 30 | LJ_FUNC_NORET void lj_err_optype(lua_State *L, cTValue *o, ErrMsg opm); 31 | LJ_FUNC_NORET void lj_err_comp(lua_State *L, cTValue *o1, cTValue *o2); 32 | LJ_FUNC_NORET void lj_err_optype_call(lua_State *L, TValue *o); 33 | LJ_FUNC_NORET void lj_err_callermsg(lua_State *L, const char *msg); 34 | LJ_FUNC_NORET void lj_err_callerv(lua_State *L, ErrMsg em, ...); 35 | LJ_FUNC_NORET void lj_err_caller(lua_State *L, ErrMsg em); 36 | LJ_FUNC_NORET void lj_err_arg(lua_State *L, int narg, ErrMsg em); 37 | LJ_FUNC_NORET void lj_err_argv(lua_State *L, int narg, ErrMsg em, ...); 38 | LJ_FUNC_NORET void lj_err_argtype(lua_State *L, int narg, const char *xname); 39 | LJ_FUNC_NORET void lj_err_argt(lua_State *L, int narg, int tt); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/lj_ff.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Fast function IDs. 3 | ** Copyright (C) 2005-2022 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-2022 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_frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Stack frames. 3 | ** Copyright (C) 2005-2022 Mike Pall. See Copyright Notice in luajit.h 4 | */ 5 | 6 | #ifndef _LJ_FRAME_H 7 | #define _LJ_FRAME_H 8 | 9 | #include "lj_obj.h" 10 | #include "lj_bc.h" 11 | 12 | /* -- Lua stack frame ----------------------------------------------------- */ 13 | 14 | /* Frame type markers in callee function slot (callee base-1). */ 15 | enum { 16 | FRAME_LUA, FRAME_C, FRAME_CONT, FRAME_VARG, 17 | FRAME_LUAP, FRAME_CP, FRAME_PCALL, FRAME_PCALLH 18 | }; 19 | #define FRAME_TYPE 3 20 | #define FRAME_P 4 21 | #define FRAME_TYPEP (FRAME_TYPE|FRAME_P) 22 | 23 | /* Macros to access and modify Lua frames. */ 24 | #define frame_gc(f) (gcref((f)->fr.func)) 25 | #define frame_func(f) (&frame_gc(f)->fn) 26 | #define frame_ftsz(f) ((f)->fr.tp.ftsz) 27 | 28 | #define frame_type(f) (frame_ftsz(f) & FRAME_TYPE) 29 | #define frame_typep(f) (frame_ftsz(f) & FRAME_TYPEP) 30 | #define frame_islua(f) (frame_type(f) == FRAME_LUA) 31 | #define frame_isc(f) (frame_type(f) == FRAME_C) 32 | #define frame_iscont(f) (frame_typep(f) == FRAME_CONT) 33 | #define frame_isvarg(f) (frame_typep(f) == FRAME_VARG) 34 | #define frame_ispcall(f) ((frame_ftsz(f) & 6) == FRAME_PCALL) 35 | 36 | #define frame_pc(f) (mref((f)->fr.tp.pcr, const BCIns)) 37 | #define frame_contpc(f) (frame_pc((f)-1)) 38 | #if LJ_64 39 | #define frame_contf(f) \ 40 | ((ASMFunction)(void *)((intptr_t)lj_vm_asm_begin + \ 41 | (intptr_t)(int32_t)((f)-1)->u32.lo)) 42 | #else 43 | #define frame_contf(f) ((ASMFunction)gcrefp(((f)-1)->gcr, void)) 44 | #endif 45 | #define frame_delta(f) (frame_ftsz(f) >> 3) 46 | #define frame_sized(f) (frame_ftsz(f) & ~FRAME_TYPEP) 47 | 48 | #define frame_prevl(f) ((f) - (1+bc_a(frame_pc(f)[-1]))) 49 | #define frame_prevd(f) ((TValue *)((char *)(f) - frame_sized(f))) 50 | #define frame_prev(f) (frame_islua(f)?frame_prevl(f):frame_prevd(f)) 51 | /* Note: this macro does not skip over FRAME_VARG. */ 52 | 53 | #define setframe_pc(f, pc) (setmref((f)->fr.tp.pcr, (pc))) 54 | #define setframe_ftsz(f, sz) ((f)->fr.tp.ftsz = (sz)) 55 | #define setframe_gc(f, p) (setgcref((f)->fr.func, (p))) 56 | 57 | /* -- C stack frame ------------------------------------------------------- */ 58 | 59 | /* Macros to access and modify the C stack frame chain. */ 60 | 61 | /* These definitions must match with the arch-specific *.dasc files. */ 62 | #if LJ_TARGET_X86 63 | #define CFRAME_OFS_ERRF (15*4) 64 | #define CFRAME_OFS_NRES (14*4) 65 | #define CFRAME_OFS_PREV (13*4) 66 | #define CFRAME_OFS_L (12*4) 67 | #define CFRAME_OFS_PC (6*4) 68 | #define CFRAME_OFS_MULTRES (5*4) 69 | #define CFRAME_SIZE (12*4) 70 | #define CFRAME_SHIFT_MULTRES 0 71 | #elif LJ_TARGET_X64 72 | #if LJ_ABI_WIN 73 | #define CFRAME_OFS_PREV (13*8) 74 | #define CFRAME_OFS_PC (25*4) 75 | #define CFRAME_OFS_L (24*4) 76 | #define CFRAME_OFS_ERRF (23*4) 77 | #define CFRAME_OFS_NRES (22*4) 78 | #define CFRAME_OFS_MULTRES (21*4) 79 | #define CFRAME_SIZE (10*8) 80 | #define CFRAME_SIZE_JIT (CFRAME_SIZE + 9*16 + 4*8) 81 | #define CFRAME_SHIFT_MULTRES 0 82 | #else 83 | #define CFRAME_OFS_PREV (4*8) 84 | #define CFRAME_OFS_PC (7*4) 85 | #define CFRAME_OFS_L (6*4) 86 | #define CFRAME_OFS_ERRF (5*4) 87 | #define CFRAME_OFS_NRES (4*4) 88 | #define CFRAME_OFS_MULTRES (1*4) 89 | #if LJ_NO_UNWIND 90 | #define CFRAME_SIZE (12*8) 91 | #else 92 | #define CFRAME_SIZE (10*8) 93 | #endif 94 | #define CFRAME_SIZE_JIT (CFRAME_SIZE + 16) 95 | #define CFRAME_SHIFT_MULTRES 0 96 | #endif 97 | #elif LJ_TARGET_ARM 98 | #define CFRAME_OFS_ERRF 24 99 | #define CFRAME_OFS_NRES 20 100 | #define CFRAME_OFS_PREV 16 101 | #define CFRAME_OFS_L 12 102 | #define CFRAME_OFS_PC 8 103 | #define CFRAME_OFS_MULTRES 4 104 | #if LJ_ARCH_HASFPU 105 | #define CFRAME_SIZE 128 106 | #else 107 | #define CFRAME_SIZE 64 108 | #endif 109 | #define CFRAME_SHIFT_MULTRES 3 110 | #elif LJ_TARGET_PPC 111 | #if LJ_TARGET_XBOX360 112 | #define CFRAME_OFS_ERRF 424 113 | #define CFRAME_OFS_NRES 420 114 | #define CFRAME_OFS_PREV 400 115 | #define CFRAME_OFS_L 416 116 | #define CFRAME_OFS_PC 412 117 | #define CFRAME_OFS_MULTRES 408 118 | #define CFRAME_SIZE 384 119 | #define CFRAME_SHIFT_MULTRES 3 120 | #elif LJ_ARCH_PPC64 121 | #define CFRAME_OFS_ERRF 472 122 | #define CFRAME_OFS_NRES 468 123 | #define CFRAME_OFS_PREV 448 124 | #define CFRAME_OFS_L 464 125 | #define CFRAME_OFS_PC 460 126 | #define CFRAME_OFS_MULTRES 456 127 | #define CFRAME_SIZE 400 128 | #define CFRAME_SHIFT_MULTRES 3 129 | #else 130 | #define CFRAME_OFS_ERRF 48 131 | #define CFRAME_OFS_NRES 44 132 | #define CFRAME_OFS_PREV 40 133 | #define CFRAME_OFS_L 36 134 | #define CFRAME_OFS_PC 32 135 | #define CFRAME_OFS_MULTRES 28 136 | #define CFRAME_SIZE 272 137 | #define CFRAME_SHIFT_MULTRES 3 138 | #endif 139 | #elif LJ_TARGET_PPCSPE 140 | #define CFRAME_OFS_ERRF 28 141 | #define CFRAME_OFS_NRES 24 142 | #define CFRAME_OFS_PREV 20 143 | #define CFRAME_OFS_L 16 144 | #define CFRAME_OFS_PC 12 145 | #define CFRAME_OFS_MULTRES 8 146 | #define CFRAME_SIZE 184 147 | #define CFRAME_SHIFT_MULTRES 3 148 | #elif LJ_TARGET_MIPS 149 | #define CFRAME_OFS_ERRF 124 150 | #define CFRAME_OFS_NRES 120 151 | #define CFRAME_OFS_PREV 116 152 | #define CFRAME_OFS_L 112 153 | #define CFRAME_OFS_PC 20 154 | #define CFRAME_OFS_MULTRES 16 155 | #define CFRAME_SIZE 112 156 | #define CFRAME_SHIFT_MULTRES 3 157 | #else 158 | #error "Missing CFRAME_* definitions for this architecture" 159 | #endif 160 | 161 | #ifndef CFRAME_SIZE_JIT 162 | #define CFRAME_SIZE_JIT CFRAME_SIZE 163 | #endif 164 | 165 | #define CFRAME_RESUME 1 166 | #define CFRAME_UNWIND_FF 2 /* Only used in unwinder. */ 167 | #define CFRAME_RAWMASK (~(intptr_t)(CFRAME_RESUME|CFRAME_UNWIND_FF)) 168 | 169 | #define cframe_errfunc(cf) (*(int32_t *)(((char *)(cf))+CFRAME_OFS_ERRF)) 170 | #define cframe_nres(cf) (*(int32_t *)(((char *)(cf))+CFRAME_OFS_NRES)) 171 | #define cframe_prev(cf) (*(void **)(((char *)(cf))+CFRAME_OFS_PREV)) 172 | #define cframe_multres(cf) (*(uint32_t *)(((char *)(cf))+CFRAME_OFS_MULTRES)) 173 | #define cframe_multres_n(cf) (cframe_multres((cf)) >> CFRAME_SHIFT_MULTRES) 174 | #define cframe_L(cf) \ 175 | (&gcref(*(GCRef *)(((char *)(cf))+CFRAME_OFS_L))->th) 176 | #define cframe_pc(cf) \ 177 | (mref(*(MRef *)(((char *)(cf))+CFRAME_OFS_PC), const BCIns)) 178 | #define setcframe_L(cf, L) \ 179 | (setmref(*(MRef *)(((char *)(cf))+CFRAME_OFS_L), (L))) 180 | #define setcframe_pc(cf, pc) \ 181 | (setmref(*(MRef *)(((char *)(cf))+CFRAME_OFS_PC), (pc))) 182 | #define cframe_canyield(cf) ((intptr_t)(cf) & CFRAME_RESUME) 183 | #define cframe_unwind_ff(cf) ((intptr_t)(cf) & CFRAME_UNWIND_FF) 184 | #define cframe_raw(cf) ((void *)((intptr_t)(cf) & CFRAME_RAWMASK)) 185 | #define cframe_Lpc(L) cframe_pc(cframe_raw(L->cframe)) 186 | 187 | #endif 188 | -------------------------------------------------------------------------------- /src/lj_func.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** Function handling (prototypes, functions and upvalues). 3 | ** Copyright (C) 2005-2022 Mike Pall. See Copyright Notice in luajit.h 4 | ** 5 | ** Portions taken verbatim or adapted from the Lua interpreter. 6 | ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h 7 | */ 8 | 9 | #define lj_func_c 10 | #define LUA_CORE 11 | 12 | #include "lj_obj.h" 13 | #include "lj_gc.h" 14 | #include "lj_func.h" 15 | #include "lj_trace.h" 16 | #include "lj_vm.h" 17 | 18 | /* -- Prototypes ---------------------------------------------------------- */ 19 | 20 | void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt) 21 | { 22 | lj_mem_free(g, pt, pt->sizept); 23 | } 24 | 25 | /* -- Upvalues ------------------------------------------------------------ */ 26 | 27 | static void unlinkuv(GCupval *uv) 28 | { 29 | lua_assert(uvprev(uvnext(uv)) == uv && uvnext(uvprev(uv)) == uv); 30 | setgcrefr(uvnext(uv)->prev, uv->prev); 31 | setgcrefr(uvprev(uv)->next, uv->next); 32 | } 33 | 34 | /* Find existing open upvalue for a stack slot or create a new one. */ 35 | static GCupval *func_finduv(lua_State *L, TValue *slot) 36 | { 37 | global_State *g = G(L); 38 | GCRef *pp = &L->openupval; 39 | GCupval *p; 40 | GCupval *uv; 41 | /* Search the sorted list of open upvalues. */ 42 | while (gcref(*pp) != NULL && uvval((p = gco2uv(gcref(*pp)))) >= slot) { 43 | lua_assert(!p->closed && uvval(p) != &p->tv); 44 | if (uvval(p) == slot) { /* Found open upvalue pointing to same slot? */ 45 | if (isdead(g, obj2gco(p))) /* Resurrect it, if it's dead. */ 46 | flipwhite(obj2gco(p)); 47 | return p; 48 | } 49 | pp = &p->nextgc; 50 | } 51 | /* No matching upvalue found. Create a new one. */ 52 | uv = lj_mem_newt(L, sizeof(GCupval), GCupval); 53 | newwhite(g, uv); 54 | uv->gct = ~LJ_TUPVAL; 55 | uv->closed = 0; /* Still open. */ 56 | setmref(uv->v, slot); /* Pointing to the stack slot. */ 57 | /* NOBARRIER: The GCupval is new (marked white) and open. */ 58 | setgcrefr(uv->nextgc, *pp); /* Insert into sorted list of open upvalues. */ 59 | setgcref(*pp, obj2gco(uv)); 60 | setgcref(uv->prev, obj2gco(&g->uvhead)); /* Insert into GC list, too. */ 61 | setgcrefr(uv->next, g->uvhead.next); 62 | setgcref(uvnext(uv)->prev, obj2gco(uv)); 63 | setgcref(g->uvhead.next, obj2gco(uv)); 64 | lua_assert(uvprev(uvnext(uv)) == uv && uvnext(uvprev(uv)) == uv); 65 | return uv; 66 | } 67 | 68 | /* Create an empty and closed upvalue. */ 69 | static GCupval *func_emptyuv(lua_State *L) 70 | { 71 | GCupval *uv = (GCupval *)lj_mem_newgco(L, sizeof(GCupval)); 72 | uv->gct = ~LJ_TUPVAL; 73 | uv->closed = 1; 74 | setnilV(&uv->tv); 75 | setmref(uv->v, &uv->tv); 76 | return uv; 77 | } 78 | 79 | /* Close all open upvalues pointing to some stack level or above. */ 80 | void LJ_FASTCALL lj_func_closeuv(lua_State *L, TValue *level) 81 | { 82 | GCupval *uv; 83 | global_State *g = G(L); 84 | while (gcref(L->openupval) != NULL && 85 | uvval((uv = gco2uv(gcref(L->openupval)))) >= level) { 86 | GCobj *o = obj2gco(uv); 87 | lua_assert(!isblack(o) && !uv->closed && uvval(uv) != &uv->tv); 88 | setgcrefr(L->openupval, uv->nextgc); /* No longer in open list. */ 89 | if (isdead(g, o)) { 90 | lj_func_freeuv(g, uv); 91 | } else { 92 | unlinkuv(uv); 93 | lj_gc_closeuv(g, uv); 94 | } 95 | } 96 | } 97 | 98 | void LJ_FASTCALL lj_func_freeuv(global_State *g, GCupval *uv) 99 | { 100 | if (!uv->closed) 101 | unlinkuv(uv); 102 | lj_mem_freet(g, uv); 103 | } 104 | 105 | /* -- Functions (closures) ------------------------------------------------ */ 106 | 107 | GCfunc *lj_func_newC(lua_State *L, MSize nelems, GCtab *env) 108 | { 109 | GCfunc *fn = (GCfunc *)lj_mem_newgco(L, sizeCfunc(nelems)); 110 | fn->c.gct = ~LJ_TFUNC; 111 | fn->c.ffid = FF_C; 112 | fn->c.nupvalues = (uint8_t)nelems; 113 | /* NOBARRIER: The GCfunc is new (marked white). */ 114 | setmref(fn->c.pc, &G(L)->bc_cfunc_ext); 115 | setgcref(fn->c.env, obj2gco(env)); 116 | return fn; 117 | } 118 | 119 | static GCfunc *func_newL(lua_State *L, GCproto *pt, GCtab *env) 120 | { 121 | uint32_t count; 122 | GCfunc *fn = (GCfunc *)lj_mem_newgco(L, sizeLfunc((MSize)pt->sizeuv)); 123 | fn->l.gct = ~LJ_TFUNC; 124 | fn->l.ffid = FF_LUA; 125 | fn->l.nupvalues = 0; /* Set to zero until upvalues are initialized. */ 126 | /* NOBARRIER: Really a setgcref. But the GCfunc is new (marked white). */ 127 | setmref(fn->l.pc, proto_bc(pt)); 128 | setgcref(fn->l.env, obj2gco(env)); 129 | /* Saturating 3 bit counter (0..7) for created closures. */ 130 | count = (uint32_t)pt->flags + PROTO_CLCOUNT; 131 | pt->flags = (uint8_t)(count - ((count >> PROTO_CLC_BITS) & PROTO_CLCOUNT)); 132 | return fn; 133 | } 134 | 135 | /* Create a new Lua function with empty upvalues. */ 136 | GCfunc *lj_func_newL_empty(lua_State *L, GCproto *pt, GCtab *env) 137 | { 138 | GCfunc *fn = func_newL(L, pt, env); 139 | MSize i, nuv = pt->sizeuv; 140 | /* NOBARRIER: The GCfunc is new (marked white). */ 141 | for (i = 0; i < nuv; i++) { 142 | GCupval *uv = func_emptyuv(L); 143 | int32_t v = proto_uv(pt)[i]; 144 | uv->immutable = ((v / PROTO_UV_IMMUTABLE) & 1); 145 | uv->dhash = (uint32_t)(uintptr_t)pt ^ (v << 24); 146 | setgcref(fn->l.uvptr[i], obj2gco(uv)); 147 | } 148 | fn->l.nupvalues = (uint8_t)nuv; 149 | return fn; 150 | } 151 | 152 | /* Do a GC check and create a new Lua function with inherited upvalues. */ 153 | GCfunc *lj_func_newL_gc(lua_State *L, GCproto *pt, GCfuncL *parent) 154 | { 155 | GCfunc *fn; 156 | GCRef *puv; 157 | MSize i, nuv; 158 | TValue *base; 159 | lj_gc_check_fixtop(L); 160 | fn = func_newL(L, pt, tabref(parent->env)); 161 | /* NOBARRIER: The GCfunc is new (marked white). */ 162 | puv = parent->uvptr; 163 | nuv = pt->sizeuv; 164 | base = L->base; 165 | for (i = 0; i < nuv; i++) { 166 | uint32_t v = proto_uv(pt)[i]; 167 | GCupval *uv; 168 | if ((v & PROTO_UV_LOCAL)) { 169 | uv = func_finduv(L, base + (v & 0xff)); 170 | uv->immutable = ((v / PROTO_UV_IMMUTABLE) & 1); 171 | uv->dhash = (uint32_t)(uintptr_t)mref(parent->pc, char) ^ (v << 24); 172 | } else { 173 | uv = &gcref(puv[v])->uv; 174 | } 175 | setgcref(fn->l.uvptr[i], obj2gco(uv)); 176 | } 177 | fn->l.nupvalues = (uint8_t)nuv; 178 | return fn; 179 | } 180 | 181 | void LJ_FASTCALL lj_func_free(global_State *g, GCfunc *fn) 182 | { 183 | MSize size = isluafunc(fn) ? sizeLfunc((MSize)fn->l.nupvalues) : 184 | sizeCfunc((MSize)fn->c.nupvalues); 185 | lj_mem_free(g, fn, size); 186 | } 187 | 188 | -------------------------------------------------------------------------------- /src/lj_func.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Function handling (prototypes, functions and upvalues). 3 | ** Copyright (C) 2005-2022 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-2022 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 | lua_assert(isblack(o) && !isdead(g, o)); 85 | lua_assert(g->gc.state != GCSfinalize && g->gc.state != GCSpause); 86 | black2gray(o); 87 | setgcrefr(t->gclist, g->gc.grayagain); 88 | setgcref(g->gc.grayagain, o); 89 | } 90 | 91 | /* Barrier for stores to table objects. TValue and GCobj variant. */ 92 | #define lj_gc_anybarriert(L, t) \ 93 | { if (LJ_UNLIKELY(isblack(obj2gco(t)))) lj_gc_barrierback(G(L), (t)); } 94 | #define lj_gc_barriert(L, t, tv) \ 95 | { if (tviswhite(tv) && isblack(obj2gco(t))) \ 96 | lj_gc_barrierback(G(L), (t)); } 97 | #define lj_gc_objbarriert(L, t, o) \ 98 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) \ 99 | lj_gc_barrierback(G(L), (t)); } 100 | 101 | /* Barrier for stores to any other object. TValue and GCobj variant. */ 102 | #define lj_gc_barrier(L, p, tv) \ 103 | { if (tviswhite(tv) && isblack(obj2gco(p))) \ 104 | lj_gc_barrierf(G(L), obj2gco(p), gcV(tv)); } 105 | #define lj_gc_objbarrier(L, p, o) \ 106 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ 107 | lj_gc_barrierf(G(L), obj2gco(p), obj2gco(o)); } 108 | 109 | /* Allocator. */ 110 | LJ_FUNC void *lj_mem_realloc(lua_State *L, void *p, MSize osz, MSize nsz); 111 | LJ_FUNC void * LJ_FASTCALL lj_mem_newgco(lua_State *L, MSize size); 112 | LJ_FUNC void *lj_mem_grow(lua_State *L, void *p, 113 | MSize *szp, MSize lim, MSize esz); 114 | 115 | #define lj_mem_new(L, s) lj_mem_realloc(L, NULL, 0, (s)) 116 | 117 | static LJ_AINLINE void lj_mem_free(global_State *g, void *p, size_t osize) 118 | { 119 | g->gc.total -= (MSize)osize; 120 | g->allocf(g->allocd, p, osize, 0); 121 | } 122 | 123 | #define lj_mem_newvec(L, n, t) ((t *)lj_mem_new(L, (MSize)((n)*sizeof(t)))) 124 | #define lj_mem_reallocvec(L, p, on, n, t) \ 125 | ((p) = (t *)lj_mem_realloc(L, p, (on)*sizeof(t), (MSize)((n)*sizeof(t)))) 126 | #define lj_mem_growvec(L, p, n, m, t) \ 127 | ((p) = (t *)lj_mem_grow(L, (p), &(n), (m), (MSize)sizeof(t))) 128 | #define lj_mem_freevec(g, p, n, t) lj_mem_free(g, (p), (n)*sizeof(t)) 129 | 130 | #define lj_mem_newobj(L, t) ((t *)lj_mem_newgco(L, sizeof(t))) 131 | #define lj_mem_newt(L, s, t) ((t *)lj_mem_new(L, (s))) 132 | #define lj_mem_freet(g, p) lj_mem_free(g, (p), sizeof(*(p))) 133 | 134 | #endif 135 | -------------------------------------------------------------------------------- /src/lj_gdbjit.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Client for the GDB JIT API. 3 | ** Copyright (C) 2005-2022 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_iropt.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Common header for IR emitter and optimizations. 3 | ** Copyright (C) 2005-2022 Mike Pall. See Copyright Notice in luajit.h 4 | */ 5 | 6 | #ifndef _LJ_IROPT_H 7 | #define _LJ_IROPT_H 8 | 9 | #include 10 | 11 | #include "lj_obj.h" 12 | #include "lj_jit.h" 13 | 14 | #if LJ_HASJIT 15 | /* IR emitter. */ 16 | LJ_FUNC void LJ_FASTCALL lj_ir_growtop(jit_State *J); 17 | LJ_FUNC TRef LJ_FASTCALL lj_ir_emit(jit_State *J); 18 | 19 | /* Save current IR in J->fold.ins, but do not emit it (yet). */ 20 | static LJ_AINLINE void lj_ir_set_(jit_State *J, uint16_t ot, IRRef1 a, IRRef1 b) 21 | { 22 | J->fold.ins.ot = ot; J->fold.ins.op1 = a; J->fold.ins.op2 = b; 23 | } 24 | 25 | #define lj_ir_set(J, ot, a, b) \ 26 | lj_ir_set_(J, (uint16_t)(ot), (IRRef1)(a), (IRRef1)(b)) 27 | 28 | /* Get ref of next IR instruction and optionally grow IR. 29 | ** Note: this may invalidate all IRIns*! 30 | */ 31 | static LJ_AINLINE IRRef lj_ir_nextins(jit_State *J) 32 | { 33 | IRRef ref = J->cur.nins; 34 | if (LJ_UNLIKELY(ref >= J->irtoplim)) lj_ir_growtop(J); 35 | J->cur.nins = ref + 1; 36 | return ref; 37 | } 38 | 39 | /* Interning of constants. */ 40 | LJ_FUNC TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k); 41 | LJ_FUNC void lj_ir_k64_freeall(jit_State *J); 42 | LJ_FUNC TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv); 43 | LJ_FUNC cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64); 44 | LJ_FUNC TRef lj_ir_knum_u64(jit_State *J, uint64_t u64); 45 | LJ_FUNC TRef lj_ir_knumint(jit_State *J, lua_Number n); 46 | LJ_FUNC TRef lj_ir_kint64(jit_State *J, uint64_t u64); 47 | LJ_FUNC TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t); 48 | LJ_FUNC TRef lj_ir_kptr_(jit_State *J, IROp op, void *ptr); 49 | LJ_FUNC TRef lj_ir_knull(jit_State *J, IRType t); 50 | LJ_FUNC TRef lj_ir_kslot(jit_State *J, TRef key, IRRef slot); 51 | 52 | #if LJ_64 53 | #define lj_ir_kintp(J, k) lj_ir_kint64(J, (uint64_t)(k)) 54 | #else 55 | #define lj_ir_kintp(J, k) lj_ir_kint(J, (int32_t)(k)) 56 | #endif 57 | 58 | static LJ_AINLINE TRef lj_ir_knum(jit_State *J, lua_Number n) 59 | { 60 | TValue tv; 61 | tv.n = n; 62 | return lj_ir_knum_u64(J, tv.u64); 63 | } 64 | 65 | #define lj_ir_kstr(J, str) lj_ir_kgc(J, obj2gco((str)), IRT_STR) 66 | #define lj_ir_ktab(J, tab) lj_ir_kgc(J, obj2gco((tab)), IRT_TAB) 67 | #define lj_ir_kfunc(J, func) lj_ir_kgc(J, obj2gco((func)), IRT_FUNC) 68 | #define lj_ir_kptr(J, ptr) lj_ir_kptr_(J, IR_KPTR, (ptr)) 69 | #define lj_ir_kkptr(J, ptr) lj_ir_kptr_(J, IR_KKPTR, (ptr)) 70 | 71 | /* Special FP constants. */ 72 | #define lj_ir_knum_zero(J) lj_ir_knum_u64(J, U64x(00000000,00000000)) 73 | #define lj_ir_knum_one(J) lj_ir_knum_u64(J, U64x(3ff00000,00000000)) 74 | #define lj_ir_knum_tobit(J) lj_ir_knum_u64(J, U64x(43380000,00000000)) 75 | 76 | /* Special 128 bit SIMD constants. */ 77 | #define lj_ir_knum_abs(J) lj_ir_k64(J, IR_KNUM, LJ_KSIMD(J, LJ_KSIMD_ABS)) 78 | #define lj_ir_knum_neg(J) lj_ir_k64(J, IR_KNUM, LJ_KSIMD(J, LJ_KSIMD_NEG)) 79 | 80 | /* Access to constants. */ 81 | LJ_FUNC void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir); 82 | 83 | /* Convert IR operand types. */ 84 | LJ_FUNC TRef LJ_FASTCALL lj_ir_tonumber(jit_State *J, TRef tr); 85 | LJ_FUNC TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr); 86 | LJ_FUNC TRef LJ_FASTCALL lj_ir_tostr(jit_State *J, TRef tr); 87 | 88 | /* Miscellaneous IR ops. */ 89 | LJ_FUNC int lj_ir_numcmp(lua_Number a, lua_Number b, IROp op); 90 | LJ_FUNC int lj_ir_strcmp(GCstr *a, GCstr *b, IROp op); 91 | LJ_FUNC void lj_ir_rollback(jit_State *J, IRRef ref); 92 | 93 | /* Emit IR instructions with on-the-fly optimizations. */ 94 | LJ_FUNC TRef LJ_FASTCALL lj_opt_fold(jit_State *J); 95 | LJ_FUNC TRef LJ_FASTCALL lj_opt_cse(jit_State *J); 96 | LJ_FUNC TRef LJ_FASTCALL lj_opt_cselim(jit_State *J, IRRef lim); 97 | 98 | /* Special return values for the fold functions. */ 99 | enum { 100 | NEXTFOLD, /* Couldn't fold, pass on. */ 101 | RETRYFOLD, /* Retry fold with modified fins. */ 102 | KINTFOLD, /* Return ref for int constant in fins->i. */ 103 | FAILFOLD, /* Guard would always fail. */ 104 | DROPFOLD, /* Guard eliminated. */ 105 | MAX_FOLD 106 | }; 107 | 108 | #define INTFOLD(k) ((J->fold.ins.i = (k)), (TRef)KINTFOLD) 109 | #define INT64FOLD(k) (lj_ir_kint64(J, (k))) 110 | #define CONDFOLD(cond) ((TRef)FAILFOLD + (TRef)(cond)) 111 | #define LEFTFOLD (J->fold.ins.op1) 112 | #define RIGHTFOLD (J->fold.ins.op2) 113 | #define CSEFOLD (lj_opt_cse(J)) 114 | #define EMITFOLD (lj_ir_emit(J)) 115 | 116 | /* Load/store forwarding. */ 117 | LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_aload(jit_State *J); 118 | LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_hload(jit_State *J); 119 | LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_uload(jit_State *J); 120 | LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_fload(jit_State *J); 121 | LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_xload(jit_State *J); 122 | LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_tab_len(jit_State *J); 123 | LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_hrefk(jit_State *J); 124 | LJ_FUNC int LJ_FASTCALL lj_opt_fwd_href_nokey(jit_State *J); 125 | LJ_FUNC int LJ_FASTCALL lj_opt_fwd_tptr(jit_State *J, IRRef lim); 126 | LJ_FUNC int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref); 127 | 128 | /* Dead-store elimination. */ 129 | LJ_FUNC TRef LJ_FASTCALL lj_opt_dse_ahstore(jit_State *J); 130 | LJ_FUNC TRef LJ_FASTCALL lj_opt_dse_ustore(jit_State *J); 131 | LJ_FUNC TRef LJ_FASTCALL lj_opt_dse_fstore(jit_State *J); 132 | LJ_FUNC TRef LJ_FASTCALL lj_opt_dse_xstore(jit_State *J); 133 | 134 | /* Narrowing. */ 135 | LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_convert(jit_State *J); 136 | LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_index(jit_State *J, TRef key); 137 | LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_toint(jit_State *J, TRef tr); 138 | LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_tobit(jit_State *J, TRef tr); 139 | #if LJ_HASFFI 140 | LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_cindex(jit_State *J, TRef key); 141 | #endif 142 | LJ_FUNC TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc, 143 | TValue *vb, TValue *vc, IROp op); 144 | LJ_FUNC TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc); 145 | LJ_FUNC TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc); 146 | LJ_FUNC TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc); 147 | LJ_FUNC IRType lj_opt_narrow_forl(jit_State *J, cTValue *forbase); 148 | 149 | /* Optimization passes. */ 150 | LJ_FUNC void lj_opt_dce(jit_State *J); 151 | LJ_FUNC int lj_opt_loop(jit_State *J); 152 | #if LJ_SOFTFP || (LJ_32 && LJ_HASFFI) 153 | LJ_FUNC void lj_opt_split(jit_State *J); 154 | #else 155 | #define lj_opt_split(J) UNUSED(J) 156 | #endif 157 | LJ_FUNC void lj_opt_sink(jit_State *J); 158 | 159 | #endif 160 | 161 | #endif 162 | -------------------------------------------------------------------------------- /src/lj_lex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Lexical analyzer. 3 | ** Copyright (C) 2005-2022 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 LexToken; 34 | 35 | /* Combined bytecode ins/line. Only used during bytecode generation. */ 36 | typedef struct BCInsLine { 37 | BCIns ins; /* Bytecode instruction. */ 38 | BCLine line; /* Line number for this bytecode. */ 39 | } BCInsLine; 40 | 41 | /* Info for local variables. Only used during bytecode generation. */ 42 | typedef struct VarInfo { 43 | GCRef name; /* Local variable name or goto/label name. */ 44 | BCPos startpc; /* First point where the local variable is active. */ 45 | BCPos endpc; /* First point where the local variable is dead. */ 46 | uint8_t slot; /* Variable slot. */ 47 | uint8_t info; /* Variable/goto/label info. */ 48 | } VarInfo; 49 | 50 | /* Lua lexer state. */ 51 | typedef struct LexState { 52 | struct FuncState *fs; /* Current FuncState. Defined in lj_parse.c. */ 53 | struct lua_State *L; /* Lua state. */ 54 | TValue tokenval; /* Current token value. */ 55 | TValue lookaheadval; /* Lookahead token value. */ 56 | int current; /* Current character (charint). */ 57 | LexToken token; /* Current token. */ 58 | LexToken lookahead; /* Lookahead token. */ 59 | MSize n; /* Bytes left in input buffer. */ 60 | const char *p; /* Current position in input buffer. */ 61 | SBuf sb; /* String buffer for tokens. */ 62 | lua_Reader rfunc; /* Reader callback. */ 63 | void *rdata; /* Reader callback data. */ 64 | BCLine linenumber; /* Input line counter. */ 65 | BCLine lastline; /* Line of last token. */ 66 | GCstr *chunkname; /* Current chunk name (interned string). */ 67 | const char *chunkarg; /* Chunk name argument. */ 68 | const char *mode; /* Allow loading bytecode (b) and/or source text (t). */ 69 | VarInfo *vstack; /* Stack for names and extents of local variables. */ 70 | MSize sizevstack; /* Size of variable stack. */ 71 | MSize vtop; /* Top of variable stack. */ 72 | BCInsLine *bcstack; /* Stack for bytecode instructions/line numbers. */ 73 | MSize sizebcstack; /* Size of bytecode stack. */ 74 | uint32_t level; /* Syntactical nesting level. */ 75 | int endmark; /* Trust bytecode end marker, even if not at EOF. */ 76 | } LexState; 77 | 78 | LJ_FUNC int lj_lex_setup(lua_State *L, LexState *ls); 79 | LJ_FUNC void lj_lex_cleanup(lua_State *L, LexState *ls); 80 | LJ_FUNC void lj_lex_next(LexState *ls); 81 | LJ_FUNC LexToken lj_lex_lookahead(LexState *ls); 82 | LJ_FUNC const char *lj_lex_token2str(LexState *ls, LexToken token); 83 | LJ_FUNC_NORET void lj_lex_error(LexState *ls, LexToken token, ErrMsg em, ...); 84 | LJ_FUNC void lj_lex_init(lua_State *L); 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /src/lj_lib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Library function support. 3 | ** Copyright (C) 2005-2022 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 int32_t lj_lib_checkbit(lua_State *L, int narg); 45 | LJ_FUNC GCfunc *lj_lib_checkfunc(lua_State *L, int narg); 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 | 50 | /* Avoid including lj_frame.h. */ 51 | #define lj_lib_upvalue(L, n) \ 52 | (&gcref((L->base-1)->fr.func)->fn.c.upvalue[(n)-1]) 53 | 54 | #if LJ_TARGET_WINDOWS 55 | #define lj_lib_checkfpu(L) \ 56 | do { setnumV(L->top++, (lua_Number)1437217655); \ 57 | if (lua_tointeger(L, -1) != 1437217655) lj_err_caller(L, LJ_ERR_BADFPU); \ 58 | L->top--; } while (0) 59 | #else 60 | #define lj_lib_checkfpu(L) UNUSED(L) 61 | #endif 62 | 63 | /* Push internal function on the stack. */ 64 | static LJ_AINLINE void lj_lib_pushcc(lua_State *L, lua_CFunction f, 65 | int id, int n) 66 | { 67 | GCfunc *fn; 68 | lua_pushcclosure(L, f, n); 69 | fn = funcV(L->top-1); 70 | fn->c.ffid = (uint8_t)id; 71 | setmref(fn->c.pc, &G(L)->bc_cfunc_int); 72 | } 73 | 74 | #define lj_lib_pushcf(L, fn, id) (lj_lib_pushcc(L, (fn), (id), 0)) 75 | 76 | /* Library function declarations. Scanned by buildvm. */ 77 | #define LJLIB_CF(name) static int lj_cf_##name(lua_State *L) 78 | #define LJLIB_ASM(name) static int lj_ffh_##name(lua_State *L) 79 | #define LJLIB_ASM_(name) 80 | #define LJLIB_SET(name) 81 | #define LJLIB_PUSH(arg) 82 | #define LJLIB_REC(handler) 83 | #define LJLIB_NOREGUV 84 | #define LJLIB_NOREG 85 | 86 | #define LJ_LIB_REG(L, regname, name) \ 87 | lj_lib_register(L, regname, lj_lib_init_##name, lj_lib_cf_##name) 88 | 89 | LJ_FUNC void lj_lib_register(lua_State *L, const char *libname, 90 | const uint8_t *init, const lua_CFunction *cf); 91 | 92 | /* Library init data tags. */ 93 | #define LIBINIT_LENMASK 0x3f 94 | #define LIBINIT_TAGMASK 0xc0 95 | #define LIBINIT_CF 0x00 96 | #define LIBINIT_ASM 0x40 97 | #define LIBINIT_ASM_ 0x80 98 | #define LIBINIT_STRING 0xc0 99 | #define LIBINIT_MAXSTR 0x39 100 | #define LIBINIT_SET 0xfa 101 | #define LIBINIT_NUMBER 0xfb 102 | #define LIBINIT_COPY 0xfc 103 | #define LIBINIT_LASTCL 0xfd 104 | #define LIBINIT_FFID 0xfe 105 | #define LIBINIT_END 0xff 106 | 107 | /* Exported library functions. */ 108 | 109 | typedef struct RandomState RandomState; 110 | LJ_FUNC uint64_t LJ_FASTCALL lj_math_random_step(RandomState *rs); 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /src/lj_load.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** Load and dump code. 3 | ** Copyright (C) 2005-2022 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_str.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 && !strchr(ls->mode, bc ? 'b' : 't')) { 38 | setstrV(L, L->top++, lj_err_str(L, LJ_ERR_XMODE)); 39 | lj_err_throw(L, LUA_ERRSYNTAX); 40 | } 41 | pt = bc ? lj_bcread(ls) : lj_parse(ls); 42 | fn = lj_func_newL_empty(L, pt, tabref(L->env)); 43 | /* Don't combine above/below into one statement. */ 44 | setfuncV(L, L->top++, fn); 45 | return NULL; 46 | } 47 | 48 | LUA_API int lua_loadx(lua_State *L, lua_Reader reader, void *data, 49 | const char *chunkname, const char *mode) 50 | { 51 | LexState ls; 52 | int status; 53 | ls.rfunc = reader; 54 | ls.rdata = data; 55 | ls.chunkarg = chunkname ? chunkname : "?"; 56 | ls.mode = mode; 57 | lj_str_initbuf(&ls.sb); 58 | status = lj_vm_cpcall(L, NULL, &ls, cpparser); 59 | lj_lex_cleanup(L, &ls); 60 | lj_gc_check(L); 61 | return status; 62 | } 63 | 64 | LUA_API int lua_load(lua_State *L, lua_Reader reader, void *data, 65 | const char *chunkname) 66 | { 67 | return lua_loadx(L, reader, data, chunkname, NULL); 68 | } 69 | 70 | typedef struct FileReaderCtx { 71 | FILE *fp; 72 | char buf[LUAL_BUFFERSIZE]; 73 | } FileReaderCtx; 74 | 75 | static const char *reader_file(lua_State *L, void *ud, size_t *size) 76 | { 77 | FileReaderCtx *ctx = (FileReaderCtx *)ud; 78 | UNUSED(L); 79 | if (feof(ctx->fp)) return NULL; 80 | *size = fread(ctx->buf, 1, sizeof(ctx->buf), ctx->fp); 81 | return *size > 0 ? ctx->buf : NULL; 82 | } 83 | 84 | LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename, 85 | const char *mode) 86 | { 87 | FileReaderCtx ctx; 88 | int status; 89 | const char *chunkname; 90 | if (filename) { 91 | ctx.fp = fopen(filename, "rb"); 92 | if (ctx.fp == NULL) { 93 | lua_pushfstring(L, "cannot open %s: %s", filename, strerror(errno)); 94 | return LUA_ERRFILE; 95 | } 96 | chunkname = lua_pushfstring(L, "@%s", filename); 97 | } else { 98 | ctx.fp = stdin; 99 | chunkname = "=stdin"; 100 | } 101 | status = lua_loadx(L, reader_file, &ctx, chunkname, mode); 102 | if (ferror(ctx.fp)) { 103 | L->top -= filename ? 2 : 1; 104 | lua_pushfstring(L, "cannot read %s: %s", chunkname+1, strerror(errno)); 105 | if (filename) 106 | fclose(ctx.fp); 107 | return LUA_ERRFILE; 108 | } 109 | if (filename) { 110 | L->top--; 111 | copyTV(L, L->top-1, L->top); 112 | fclose(ctx.fp); 113 | } 114 | return status; 115 | } 116 | 117 | LUALIB_API int luaL_loadfile(lua_State *L, const char *filename) 118 | { 119 | return luaL_loadfilex(L, filename, NULL); 120 | } 121 | 122 | typedef struct StringReaderCtx { 123 | const char *str; 124 | size_t size; 125 | } StringReaderCtx; 126 | 127 | static const char *reader_string(lua_State *L, void *ud, size_t *size) 128 | { 129 | StringReaderCtx *ctx = (StringReaderCtx *)ud; 130 | UNUSED(L); 131 | if (ctx->size == 0) return NULL; 132 | *size = ctx->size; 133 | ctx->size = 0; 134 | return ctx->str; 135 | } 136 | 137 | LUALIB_API int luaL_loadbufferx(lua_State *L, const char *buf, size_t size, 138 | const char *name, const char *mode) 139 | { 140 | StringReaderCtx ctx; 141 | ctx.str = buf; 142 | ctx.size = size; 143 | return lua_loadx(L, reader_string, &ctx, name, mode); 144 | } 145 | 146 | LUALIB_API int luaL_loadbuffer(lua_State *L, const char *buf, size_t size, 147 | const char *name) 148 | { 149 | return luaL_loadbufferx(L, buf, size, name, NULL); 150 | } 151 | 152 | LUALIB_API int luaL_loadstring(lua_State *L, const char *s) 153 | { 154 | return luaL_loadbuffer(L, s, strlen(s), s); 155 | } 156 | 157 | /* -- Dump bytecode ------------------------------------------------------- */ 158 | 159 | LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data) 160 | { 161 | cTValue *o = L->top-1; 162 | api_check(L, L->top > L->base); 163 | if (tvisfunc(o) && isluafunc(funcV(o))) 164 | return lj_bcwrite(L, funcproto(funcV(o)), writer, data, 0); 165 | else 166 | return 1; 167 | } 168 | 169 | -------------------------------------------------------------------------------- /src/lj_mcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Machine code management. 3 | ** Copyright (C) 2005-2022 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-2022 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_call(lua_State *L, TValue *func, TValue *top); 35 | LJ_FUNCA void LJ_FASTCALL lj_meta_for(lua_State *L, TValue *o); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/lj_obj.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** Miscellaneous object handling. 3 | ** Copyright (C) 2005-2022 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_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 | -------------------------------------------------------------------------------- /src/lj_opt_dce.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** DCE: Dead Code Elimination. Pre-LOOP only -- ASM already performs DCE. 3 | ** Copyright (C) 2005-2022 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 | pchain[ir->o] = &ir->prev; 48 | } else if (!ir_sideeff(ir)) { 49 | *pchain[ir->o] = ir->prev; /* Reroute original instruction chain. */ 50 | lj_ir_nop(ir); 51 | continue; 52 | } 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-2022 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_record.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Trace recorder (bytecode -> SSA IR). 3 | ** Copyright (C) 2005-2022 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 TRef lj_record_constify(jit_State *J, cTValue *o); 32 | 33 | LJ_FUNC void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs); 34 | LJ_FUNC void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs); 35 | LJ_FUNC void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults); 36 | 37 | LJ_FUNC int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm); 38 | LJ_FUNC TRef lj_record_idx(jit_State *J, RecordIndex *ix); 39 | 40 | LJ_FUNC void lj_record_ins(jit_State *J); 41 | LJ_FUNC void lj_record_setup(jit_State *J); 42 | #endif 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/lj_snap.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Snapshot handling. 3 | ** Copyright (C) 2005-2022 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(GCtrace *T, SnapNo snapno, IRIns *ir); 17 | LJ_FUNC void lj_snap_replay(jit_State *J, GCtrace *T); 18 | LJ_FUNC const BCIns *lj_snap_restore(jit_State *J, void *exptr); 19 | LJ_FUNC void lj_snap_grow_buf_(jit_State *J, MSize need); 20 | LJ_FUNC void lj_snap_grow_map_(jit_State *J, MSize need); 21 | 22 | static LJ_AINLINE void lj_snap_grow_buf(jit_State *J, MSize need) 23 | { 24 | if (LJ_UNLIKELY(need > J->sizesnap)) lj_snap_grow_buf_(J, need); 25 | } 26 | 27 | static LJ_AINLINE void lj_snap_grow_map(jit_State *J, MSize need) 28 | { 29 | if (LJ_UNLIKELY(need > J->sizesnapmap)) lj_snap_grow_map_(J, need); 30 | } 31 | 32 | #endif 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/lj_state.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** State and stack handling. 3 | ** Copyright (C) 2005-2022 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 | 22 | static LJ_AINLINE void lj_state_checkstack(lua_State *L, MSize need) 23 | { 24 | if ((mref(L->maxstack, char) - (char *)L->top) <= 25 | (ptrdiff_t)need*(ptrdiff_t)sizeof(TValue)) 26 | lj_state_growstack(L, need); 27 | } 28 | 29 | LJ_FUNC lua_State *lj_state_new(lua_State *L); 30 | LJ_FUNC void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L); 31 | #if LJ_64 32 | LJ_FUNC lua_State *lj_state_newstate(lua_Alloc f, void *ud); 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/lj_str.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** String handling. 3 | ** Copyright (C) 2005-2022 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 interning. */ 14 | LJ_FUNC int32_t LJ_FASTCALL lj_str_cmp(GCstr *a, GCstr *b); 15 | LJ_FUNC void lj_str_resize(lua_State *L, MSize newmask); 16 | LJ_FUNCA GCstr *lj_str_new(lua_State *L, const char *str, size_t len); 17 | LJ_FUNC void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s); 18 | 19 | #define lj_str_newz(L, s) (lj_str_new(L, s, strlen(s))) 20 | #define lj_str_newlit(L, s) (lj_str_new(L, "" s, sizeof(s)-1)) 21 | 22 | /* Type conversions. */ 23 | LJ_FUNC size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o); 24 | LJ_FUNC char * LJ_FASTCALL lj_str_bufint(char *p, int32_t k); 25 | LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np); 26 | LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k); 27 | LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o); 28 | 29 | #define LJ_STR_INTBUF (1+10) 30 | #define LJ_STR_NUMBUF LUAI_MAXNUMBER2STR 31 | 32 | /* String formatting. */ 33 | LJ_FUNC const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp); 34 | LJ_FUNC const char *lj_str_pushf(lua_State *L, const char *fmt, ...) 35 | #if defined(__GNUC__) 36 | __attribute__ ((format (printf, 2, 3))) 37 | #endif 38 | ; 39 | 40 | /* Resizable string buffers. Struct definition in lj_obj.h. */ 41 | LJ_FUNC char *lj_str_needbuf(lua_State *L, SBuf *sb, MSize sz); 42 | 43 | #define lj_str_initbuf(sb) ((sb)->buf = NULL, (sb)->sz = 0) 44 | #define lj_str_resetbuf(sb) ((sb)->n = 0) 45 | #define lj_str_resizebuf(L, sb, size) \ 46 | ((sb)->buf = (char *)lj_mem_realloc(L, (sb)->buf, (sb)->sz, (size)), \ 47 | (sb)->sz = (size)) 48 | #define lj_str_freebuf(g, sb) lj_mem_free(g, (void *)(sb)->buf, (sb)->sz) 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/lj_strscan.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** String scanning. 3 | ** Copyright (C) 2005-2022 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, TValue *o, uint32_t opt); 26 | LJ_FUNC int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o); 27 | #if LJ_DUALNUM 28 | LJ_FUNC int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o); 29 | #else 30 | #define lj_strscan_number(s, o) lj_strscan_num((s), (o)) 31 | #endif 32 | 33 | /* Check for number or convert string to number/int in-place (!). */ 34 | static LJ_AINLINE int lj_strscan_numberobj(TValue *o) 35 | { 36 | return tvisnumber(o) || (tvisstr(o) && lj_strscan_number(strV(o), o)); 37 | } 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/lj_tab.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Table handling. 3 | ** Copyright (C) 2005-2022 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 | #define hsize2hbits(s) ((s) ? ((s)==1 ? 1 : 1+lj_fls((uint32_t)((s)-1))) : 0) 35 | 36 | LJ_FUNCA GCtab *lj_tab_new(lua_State *L, uint32_t asize, uint32_t hbits); 37 | #if LJ_HASJIT 38 | LJ_FUNC GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize); 39 | #endif 40 | LJ_FUNCA GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt); 41 | LJ_FUNC void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t); 42 | #if LJ_HASFFI 43 | LJ_FUNC void lj_tab_rehash(lua_State *L, GCtab *t); 44 | #endif 45 | LJ_FUNCA void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize); 46 | 47 | /* Caveat: all getters except lj_tab_get() can return NULL! */ 48 | 49 | LJ_FUNCA cTValue * LJ_FASTCALL lj_tab_getinth(GCtab *t, int32_t key); 50 | LJ_FUNC cTValue *lj_tab_getstr(GCtab *t, GCstr *key); 51 | LJ_FUNCA cTValue *lj_tab_get(lua_State *L, GCtab *t, cTValue *key); 52 | 53 | /* Caveat: all setters require a write barrier for the stored value. */ 54 | 55 | LJ_FUNCA TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key); 56 | LJ_FUNC TValue *lj_tab_setinth(lua_State *L, GCtab *t, int32_t key); 57 | LJ_FUNC TValue *lj_tab_setstr(lua_State *L, GCtab *t, GCstr *key); 58 | LJ_FUNC TValue *lj_tab_set(lua_State *L, GCtab *t, cTValue *key); 59 | 60 | #define inarray(t, key) ((MSize)(key) < (MSize)(t)->asize) 61 | #define arrayslot(t, i) (&tvref((t)->array)[(i)]) 62 | #define lj_tab_getint(t, key) \ 63 | (inarray((t), (key)) ? arrayslot((t), (key)) : lj_tab_getinth((t), (key))) 64 | #define lj_tab_setint(L, t, key) \ 65 | (inarray((t), (key)) ? arrayslot((t), (key)) : lj_tab_setinth(L, (t), (key))) 66 | 67 | LJ_FUNCA int lj_tab_next(lua_State *L, GCtab *t, TValue *key); 68 | LJ_FUNCA MSize LJ_FASTCALL lj_tab_len(GCtab *t); 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/lj_target.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Definitions for target CPU. 3 | ** Copyright (C) 2005-2022 Mike Pall. See Copyright Notice in luajit.h 4 | */ 5 | 6 | #ifndef _LJ_TARGET_H 7 | #define _LJ_TARGET_H 8 | 9 | #include "lj_def.h" 10 | #include "lj_arch.h" 11 | 12 | /* -- Registers and spill slots ------------------------------------------- */ 13 | 14 | /* Register type (uint8_t in ir->r). */ 15 | typedef uint32_t Reg; 16 | 17 | /* The hi-bit is NOT set for an allocated register. This means the value 18 | ** can be directly used without masking. The hi-bit is set for a register 19 | ** allocation hint or for RID_INIT, RID_SINK or RID_SUNK. 20 | */ 21 | #define RID_NONE 0x80 22 | #define RID_MASK 0x7f 23 | #define RID_INIT (RID_NONE|RID_MASK) 24 | #define RID_SINK (RID_INIT-1) 25 | #define RID_SUNK (RID_INIT-2) 26 | 27 | #define ra_noreg(r) ((r) & RID_NONE) 28 | #define ra_hasreg(r) (!((r) & RID_NONE)) 29 | 30 | /* The ra_hashint() macro assumes a previous test for ra_noreg(). */ 31 | #define ra_hashint(r) ((r) < RID_SUNK) 32 | #define ra_gethint(r) ((Reg)((r) & RID_MASK)) 33 | #define ra_sethint(rr, r) rr = (uint8_t)((r)|RID_NONE) 34 | #define ra_samehint(r1, r2) (ra_gethint((r1)^(r2)) == 0) 35 | 36 | /* Spill slot 0 means no spill slot has been allocated. */ 37 | #define SPS_NONE 0 38 | 39 | #define ra_hasspill(s) ((s) != SPS_NONE) 40 | 41 | /* Combined register and spill slot (uint16_t in ir->prev). */ 42 | typedef uint32_t RegSP; 43 | 44 | #define REGSP(r, s) ((r) + ((s) << 8)) 45 | #define REGSP_HINT(r) ((r)|RID_NONE) 46 | #define REGSP_INIT REGSP(RID_INIT, 0) 47 | 48 | #define regsp_reg(rs) ((rs) & 255) 49 | #define regsp_spill(rs) ((rs) >> 8) 50 | #define regsp_used(rs) \ 51 | (((rs) & ~REGSP(RID_MASK, 0)) != REGSP(RID_NONE, 0)) 52 | 53 | /* -- Register sets ------------------------------------------------------- */ 54 | 55 | /* Bitset for registers. 32 registers suffice for most architectures. 56 | ** Note that one set holds bits for both GPRs and FPRs. 57 | */ 58 | #if LJ_TARGET_PPC || LJ_TARGET_MIPS 59 | typedef uint64_t RegSet; 60 | #else 61 | typedef uint32_t RegSet; 62 | #endif 63 | 64 | #define RID2RSET(r) (((RegSet)1) << (r)) 65 | #define RSET_EMPTY ((RegSet)0) 66 | #define RSET_RANGE(lo, hi) ((RID2RSET((hi)-(lo))-1) << (lo)) 67 | 68 | #define rset_test(rs, r) ((int)((rs) >> (r)) & 1) 69 | #define rset_set(rs, r) (rs |= RID2RSET(r)) 70 | #define rset_clear(rs, r) (rs &= ~RID2RSET(r)) 71 | #define rset_exclude(rs, r) (rs & ~RID2RSET(r)) 72 | #if LJ_TARGET_PPC || LJ_TARGET_MIPS 73 | #define rset_picktop(rs) ((Reg)(__builtin_clzll(rs)^63)) 74 | #define rset_pickbot(rs) ((Reg)__builtin_ctzll(rs)) 75 | #else 76 | #define rset_picktop(rs) ((Reg)lj_fls(rs)) 77 | #define rset_pickbot(rs) ((Reg)lj_ffs(rs)) 78 | #endif 79 | 80 | /* -- Register allocation cost -------------------------------------------- */ 81 | 82 | /* The register allocation heuristic keeps track of the cost for allocating 83 | ** a specific register: 84 | ** 85 | ** A free register (obviously) has a cost of 0 and a 1-bit in the free mask. 86 | ** 87 | ** An already allocated register has the (non-zero) IR reference in the lowest 88 | ** bits and the result of a blended cost-model in the higher bits. 89 | ** 90 | ** The allocator first checks the free mask for a hit. Otherwise an (unrolled) 91 | ** linear search for the minimum cost is used. The search doesn't need to 92 | ** keep track of the position of the minimum, which makes it very fast. 93 | ** The lowest bits of the minimum cost show the desired IR reference whose 94 | ** register is the one to evict. 95 | ** 96 | ** Without the cost-model this degenerates to the standard heuristics for 97 | ** (reverse) linear-scan register allocation. Since code generation is done 98 | ** in reverse, a live interval extends from the last use to the first def. 99 | ** For an SSA IR the IR reference is the first (and only) def and thus 100 | ** trivially marks the end of the interval. The LSRA heuristics says to pick 101 | ** the register whose live interval has the furthest extent, i.e. the lowest 102 | ** IR reference in our case. 103 | ** 104 | ** A cost-model should take into account other factors, like spill-cost and 105 | ** restore- or rematerialization-cost, which depend on the kind of instruction. 106 | ** E.g. constants have zero spill costs, variant instructions have higher 107 | ** costs than invariants and PHIs should preferably never be spilled. 108 | ** 109 | ** Here's a first cut at simple, but effective blended cost-model for R-LSRA: 110 | ** - Due to careful design of the IR, constants already have lower IR 111 | ** references than invariants and invariants have lower IR references 112 | ** than variants. 113 | ** - The cost in the upper 16 bits is the sum of the IR reference and a 114 | ** weighted score. The score currently only takes into account whether 115 | ** the IRT_ISPHI bit is set in the instruction type. 116 | ** - The PHI weight is the minimum distance (in IR instructions) a PHI 117 | ** reference has to be further apart from a non-PHI reference to be spilled. 118 | ** - It should be a power of two (for speed) and must be between 2 and 32768. 119 | ** Good values for the PHI weight seem to be between 40 and 150. 120 | ** - Further study is required. 121 | */ 122 | #define REGCOST_PHI_WEIGHT 64 123 | 124 | /* Cost for allocating a specific register. */ 125 | typedef uint32_t RegCost; 126 | 127 | /* Note: assumes 16 bit IRRef1. */ 128 | #define REGCOST(cost, ref) ((RegCost)(ref) + ((RegCost)(cost) << 16)) 129 | #define regcost_ref(rc) ((IRRef1)(rc)) 130 | 131 | #define REGCOST_T(t) \ 132 | ((RegCost)((t)&IRT_ISPHI) * (((RegCost)(REGCOST_PHI_WEIGHT)<<16)/IRT_ISPHI)) 133 | #define REGCOST_REF_T(ref, t) (REGCOST((ref), (ref)) + REGCOST_T((t))) 134 | 135 | /* -- Target-specific definitions ----------------------------------------- */ 136 | 137 | #if LJ_TARGET_X86ORX64 138 | #include "lj_target_x86.h" 139 | #elif LJ_TARGET_ARM 140 | #include "lj_target_arm.h" 141 | #elif LJ_TARGET_PPC 142 | #include "lj_target_ppc.h" 143 | #elif LJ_TARGET_MIPS 144 | #include "lj_target_mips.h" 145 | #else 146 | #error "Missing include for target CPU" 147 | #endif 148 | 149 | #ifdef EXITSTUBS_PER_GROUP 150 | /* Return the address of an exit stub. */ 151 | static LJ_AINLINE char *exitstub_addr_(char **group, uint32_t exitno) 152 | { 153 | lua_assert(group[exitno / EXITSTUBS_PER_GROUP] != NULL); 154 | return (char *)group[exitno / EXITSTUBS_PER_GROUP] + 155 | EXITSTUB_SPACING*(exitno % EXITSTUBS_PER_GROUP); 156 | } 157 | /* Avoid dependence on lj_jit.h if only including lj_target.h. */ 158 | #define exitstub_addr(J, exitno) \ 159 | ((MCode *)exitstub_addr_((char **)((J)->exitstubgroup), (exitno))) 160 | #endif 161 | 162 | #endif 163 | -------------------------------------------------------------------------------- /src/lj_trace.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Trace management. 3 | ** Copyright (C) 2005-2022 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 void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T); 27 | LJ_FUNC void lj_trace_reenableproto(GCproto *pt); 28 | LJ_FUNC void lj_trace_flushproto(global_State *g, GCproto *pt); 29 | LJ_FUNC void lj_trace_flush(jit_State *J, TraceNo traceno); 30 | LJ_FUNC int lj_trace_flushall(lua_State *L); 31 | LJ_FUNC void lj_trace_initstate(global_State *g); 32 | LJ_FUNC void lj_trace_freestate(global_State *g); 33 | 34 | /* Event handling. */ 35 | LJ_FUNC void lj_trace_ins(jit_State *J, const BCIns *pc); 36 | LJ_FUNCA void LJ_FASTCALL lj_trace_hot(jit_State *J, const BCIns *pc); 37 | LJ_FUNCA int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr); 38 | 39 | /* Signal asynchronous abort of trace or end of trace. */ 40 | #define lj_trace_abort(g) (G2J(g)->state &= ~LJ_TRACE_ACTIVE) 41 | #define lj_trace_end(J) (J->state = LJ_TRACE_END) 42 | 43 | #else 44 | 45 | #define lj_trace_flushall(L) (UNUSED(L), 0) 46 | #define lj_trace_initstate(g) UNUSED(g) 47 | #define lj_trace_freestate(g) UNUSED(g) 48 | #define lj_trace_abort(g) UNUSED(g) 49 | #define lj_trace_end(J) UNUSED(J) 50 | 51 | #endif 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/lj_traceerr.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Trace compiler error messages. 3 | ** Copyright (C) 2005-2022 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(TRACEOV, "trace too long") 11 | TREDEF(STACKOV, "trace too deep") 12 | TREDEF(SNAPOV, "too many snapshots") 13 | TREDEF(BLACKL, "blacklisted") 14 | TREDEF(NYIBC, "NYI: bytecode %d") 15 | 16 | /* Recording loop ops. */ 17 | TREDEF(LLEAVE, "leaving loop in root trace") 18 | TREDEF(LINNER, "inner loop in root trace") 19 | TREDEF(LUNROLL, "loop unroll limit reached") 20 | 21 | /* Recording calls/returns. */ 22 | TREDEF(BADTYPE, "bad argument type") 23 | TREDEF(CJITOFF, "JIT compilation disabled for function") 24 | TREDEF(CUNROLL, "call unroll limit reached") 25 | TREDEF(DOWNREC, "down-recursion, restarting") 26 | TREDEF(NYICF, "NYI: C function %s") 27 | TREDEF(NYIFF, "NYI: FastFunc %s") 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-2022 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_udata.h" 12 | 13 | GCudata *lj_udata_new(lua_State *L, MSize sz, GCtab *env) 14 | { 15 | GCudata *ud = lj_mem_newt(L, sizeof(GCudata) + sz, GCudata); 16 | global_State *g = G(L); 17 | newwhite(g, ud); /* Not finalized. */ 18 | ud->gct = ~LJ_TUDATA; 19 | ud->udtype = UDTYPE_USERDATA; 20 | ud->len = sz; 21 | /* NOBARRIER: The GCudata is new (marked white). */ 22 | setgcrefnull(ud->metatable); 23 | setgcref(ud->env, obj2gco(env)); 24 | /* Chain to userdata list (after main thread). */ 25 | setgcrefr(ud->nextgc, mainthread(g)->nextgc); 26 | setgcref(mainthread(g)->nextgc, obj2gco(ud)); 27 | return ud; 28 | } 29 | 30 | void LJ_FASTCALL lj_udata_free(global_State *g, GCudata *ud) 31 | { 32 | lj_mem_free(g, ud, sizeudata(ud)); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/lj_udata.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Userdata handling. 3 | ** Copyright (C) 2005-2022 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 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/lj_vm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Assembler VM interface definitions. 3 | ** Copyright (C) 2005-2022 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 | LJ_ASMF void lj_vm_unwind_c_eh(void); 21 | LJ_ASMF void lj_vm_unwind_ff_eh(void); 22 | #if LJ_TARGET_X86ORX64 23 | LJ_ASMF void lj_vm_unwind_rethrow(void); 24 | #endif 25 | 26 | /* Miscellaneous functions. */ 27 | #if LJ_TARGET_X86ORX64 28 | LJ_ASMF int lj_vm_cpuid(uint32_t f, uint32_t res[4]); 29 | #endif 30 | #if LJ_TARGET_PPC 31 | void lj_vm_cachesync(void *start, void *end); 32 | #endif 33 | LJ_ASMF double lj_vm_foldarith(double x, double y, int op); 34 | #if LJ_HASJIT 35 | LJ_ASMF double lj_vm_foldfpm(double x, int op); 36 | #endif 37 | #if !LJ_ARCH_HASFPU 38 | /* Declared in lj_obj.h: LJ_ASMF int32_t lj_vm_tobit(double x); */ 39 | #endif 40 | 41 | /* Dispatch targets for recording and hooks. */ 42 | LJ_ASMF void lj_vm_record(void); 43 | LJ_ASMF void lj_vm_inshook(void); 44 | LJ_ASMF void lj_vm_rethook(void); 45 | LJ_ASMF void lj_vm_callhook(void); 46 | 47 | /* Trace exit handling. */ 48 | LJ_ASMF void lj_vm_exit_handler(void); 49 | LJ_ASMF void lj_vm_exit_interp(void); 50 | 51 | /* Internal math helper functions. */ 52 | #if LJ_TARGET_X86ORX64 || LJ_TARGET_PPC 53 | #define lj_vm_floor floor 54 | #define lj_vm_ceil ceil 55 | #else 56 | LJ_ASMF double lj_vm_floor(double); 57 | LJ_ASMF double lj_vm_ceil(double); 58 | #if LJ_TARGET_ARM 59 | LJ_ASMF double lj_vm_floor_sf(double); 60 | LJ_ASMF double lj_vm_ceil_sf(double); 61 | #endif 62 | #endif 63 | #if defined(LUAJIT_NO_LOG2) || LJ_TARGET_X86ORX64 64 | LJ_ASMF double lj_vm_log2(double); 65 | #else 66 | #define lj_vm_log2 log2 67 | #endif 68 | 69 | #if LJ_HASJIT 70 | #if LJ_TARGET_X86ORX64 71 | LJ_ASMF void lj_vm_floor_sse(void); 72 | LJ_ASMF void lj_vm_ceil_sse(void); 73 | LJ_ASMF void lj_vm_trunc_sse(void); 74 | LJ_ASMF void lj_vm_exp_x87(void); 75 | LJ_ASMF void lj_vm_exp2_x87(void); 76 | LJ_ASMF void lj_vm_pow_sse(void); 77 | LJ_ASMF void lj_vm_powi_sse(void); 78 | #else 79 | #if LJ_TARGET_PPC 80 | #define lj_vm_trunc trunc 81 | #else 82 | LJ_ASMF double lj_vm_trunc(double); 83 | #if LJ_TARGET_ARM 84 | LJ_ASMF double lj_vm_trunc_sf(double); 85 | #endif 86 | #endif 87 | LJ_ASMF double lj_vm_powi(double, int32_t); 88 | #ifdef LUAJIT_NO_EXP2 89 | LJ_ASMF double lj_vm_exp2(double); 90 | #else 91 | #define lj_vm_exp2 exp2 92 | #endif 93 | #endif 94 | LJ_ASMF int32_t LJ_FASTCALL lj_vm_modi(int32_t, int32_t); 95 | #if LJ_HASFFI 96 | LJ_ASMF int lj_vm_errno(void); 97 | #endif 98 | #endif 99 | 100 | /* Continuations for metamethods. */ 101 | LJ_ASMF void lj_cont_cat(void); /* Continue with concatenation. */ 102 | LJ_ASMF void lj_cont_ra(void); /* Store result in RA from instruction. */ 103 | LJ_ASMF void lj_cont_nop(void); /* Do nothing, just continue execution. */ 104 | LJ_ASMF void lj_cont_condt(void); /* Branch if result is true. */ 105 | LJ_ASMF void lj_cont_condf(void); /* Branch if result is false. */ 106 | LJ_ASMF void lj_cont_hook(void); /* Continue from hook yield. */ 107 | 108 | enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */ 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) ((ASMFunction)(lj_vm_asm_begin + (ofs))) 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /src/lj_vmevent.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** VM event handling. 3 | ** Copyright (C) 2005-2022 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 | return savestack(L, L->top); 31 | } 32 | } 33 | g->vmevmask &= ~VMEVENT_MASK(ev); /* No handler: cache this fact. */ 34 | return 0; 35 | } 36 | 37 | void lj_vmevent_call(lua_State *L, ptrdiff_t argbase) 38 | { 39 | global_State *g = G(L); 40 | uint8_t oldmask = g->vmevmask; 41 | uint8_t oldh = hook_save(g); 42 | int status; 43 | g->vmevmask = 0; /* Disable all events. */ 44 | hook_vmevent(g); 45 | status = lj_vm_pcall(L, restorestack(L, argbase), 0+1, 0); 46 | if (LJ_UNLIKELY(status)) { 47 | /* Really shouldn't use stderr here, but where else to complain? */ 48 | L->top--; 49 | fputs("VM handler failed: ", stderr); 50 | fputs(tvisstr(L->top) ? strVdata(L->top) : "?", stderr); 51 | fputc('\n', stderr); 52 | } 53 | hook_restore(g, oldh); 54 | if (g->vmevmask != VMEVENT_NOCACHE) 55 | g->vmevmask = oldmask; /* Restore event mask, but not if not modified. */ 56 | } 57 | 58 | -------------------------------------------------------------------------------- /src/lj_vmevent.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** VM event handling. 3 | ** Copyright (C) 2005-2022 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, 0xb2d91467), 28 | VMEVENT_DEF(RECORD, 0x9284bf4f), 29 | VMEVENT_DEF(TEXIT, 0xb29df2b0), 30 | LJ_VMEVENT__MAX 31 | } VMEvent; 32 | 33 | #ifdef LUAJIT_DISABLE_VMEVENT 34 | #define lj_vmevent_send(L, ev, args) UNUSED(L) 35 | #define lj_vmevent_send_(L, ev, args, post) UNUSED(L) 36 | #else 37 | #define lj_vmevent_send(L, ev, args) \ 38 | if (G(L)->vmevmask & VMEVENT_MASK(LJ_VMEVENT_##ev)) { \ 39 | ptrdiff_t argbase = lj_vmevent_prepare(L, LJ_VMEVENT_##ev); \ 40 | if (argbase) { \ 41 | args \ 42 | lj_vmevent_call(L, argbase); \ 43 | } \ 44 | } 45 | #define lj_vmevent_send_(L, ev, args, post) \ 46 | if (G(L)->vmevmask & VMEVENT_MASK(LJ_VMEVENT_##ev)) { \ 47 | ptrdiff_t argbase = lj_vmevent_prepare(L, LJ_VMEVENT_##ev); \ 48 | if (argbase) { \ 49 | args \ 50 | lj_vmevent_call(L, argbase); \ 51 | post \ 52 | } \ 53 | } 54 | 55 | LJ_FUNC ptrdiff_t lj_vmevent_prepare(lua_State *L, VMEvent ev); 56 | LJ_FUNC void lj_vmevent_call(lua_State *L, ptrdiff_t argbase); 57 | #endif 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/lj_vmmath.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** Math helper functions for assembler VM. 3 | ** Copyright (C) 2005-2022 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 | /* -- Helper functions for generated machine code ------------------------- */ 17 | 18 | #if LJ_TARGET_X86ORX64 19 | /* Wrapper functions to avoid linker issues on OSX. */ 20 | LJ_FUNCA double lj_vm_sinh(double x) { return sinh(x); } 21 | LJ_FUNCA double lj_vm_cosh(double x) { return cosh(x); } 22 | LJ_FUNCA double lj_vm_tanh(double x) { return tanh(x); } 23 | #endif 24 | 25 | #if !LJ_TARGET_X86ORX64 26 | double lj_vm_foldarith(double x, double y, int op) 27 | { 28 | switch (op) { 29 | case IR_ADD - IR_ADD: return x+y; break; 30 | case IR_SUB - IR_ADD: return x-y; break; 31 | case IR_MUL - IR_ADD: return x*y; break; 32 | case IR_DIV - IR_ADD: return x/y; break; 33 | case IR_MOD - IR_ADD: return x-lj_vm_floor(x/y)*y; break; 34 | case IR_POW - IR_ADD: return pow(x, y); break; 35 | case IR_NEG - IR_ADD: return -x; break; 36 | case IR_ABS - IR_ADD: return fabs(x); break; 37 | #if LJ_HASJIT 38 | case IR_ATAN2 - IR_ADD: return atan2(x, y); break; 39 | case IR_LDEXP - IR_ADD: return ldexp(x, (int)y); break; 40 | case IR_MIN - IR_ADD: return x > y ? y : x; break; 41 | case IR_MAX - IR_ADD: return x < y ? y : x; break; 42 | #endif 43 | default: return x; 44 | } 45 | } 46 | #endif 47 | 48 | #if LJ_HASJIT 49 | 50 | #ifdef LUAJIT_NO_LOG2 51 | double lj_vm_log2(double a) 52 | { 53 | return log(a) * 1.4426950408889634074; 54 | } 55 | #endif 56 | 57 | #ifdef LUAJIT_NO_EXP2 58 | double lj_vm_exp2(double a) 59 | { 60 | return exp(a * 0.6931471805599453); 61 | } 62 | #endif 63 | 64 | #if !(LJ_TARGET_ARM || LJ_TARGET_PPC) 65 | int32_t LJ_FASTCALL lj_vm_modi(int32_t a, int32_t b) 66 | { 67 | uint32_t y, ua, ub; 68 | lua_assert(b != 0); /* This must be checked before using this function. */ 69 | ua = a < 0 ? (uint32_t)-a : (uint32_t)a; 70 | ub = b < 0 ? (uint32_t)-b : (uint32_t)b; 71 | y = ua % ub; 72 | if (y != 0 && (a^b) < 0) y = y - ub; 73 | if (((int32_t)y^b) < 0) y = (uint32_t)-(int32_t)y; 74 | return (int32_t)y; 75 | } 76 | #endif 77 | 78 | #if !LJ_TARGET_X86ORX64 79 | /* Unsigned x^k. */ 80 | static double lj_vm_powui(double x, uint32_t k) 81 | { 82 | double y; 83 | lua_assert(k != 0); 84 | for (; (k & 1) == 0; k >>= 1) x *= x; 85 | y = x; 86 | if ((k >>= 1) != 0) { 87 | for (;;) { 88 | x *= x; 89 | if (k == 1) break; 90 | if (k & 1) y *= x; 91 | k >>= 1; 92 | } 93 | y *= x; 94 | } 95 | return y; 96 | } 97 | 98 | /* Signed x^k. */ 99 | double lj_vm_powi(double x, int32_t k) 100 | { 101 | if (k > 1) 102 | return lj_vm_powui(x, (uint32_t)k); 103 | else if (k == 1) 104 | return x; 105 | else if (k == 0) 106 | return 1.0; 107 | else 108 | return 1.0 / lj_vm_powui(x, (uint32_t)-k); 109 | } 110 | 111 | /* Computes fpm(x) for extended math functions. */ 112 | double lj_vm_foldfpm(double x, int fpm) 113 | { 114 | switch (fpm) { 115 | case IRFPM_FLOOR: return lj_vm_floor(x); 116 | case IRFPM_CEIL: return lj_vm_ceil(x); 117 | case IRFPM_TRUNC: return lj_vm_trunc(x); 118 | case IRFPM_SQRT: return sqrt(x); 119 | case IRFPM_EXP: return exp(x); 120 | case IRFPM_EXP2: return lj_vm_exp2(x); 121 | case IRFPM_LOG: return log(x); 122 | case IRFPM_LOG2: return lj_vm_log2(x); 123 | case IRFPM_LOG10: return log10(x); 124 | case IRFPM_SIN: return sin(x); 125 | case IRFPM_COS: return cos(x); 126 | case IRFPM_TAN: return tan(x); 127 | default: lua_assert(0); 128 | } 129 | return 0; 130 | } 131 | #endif 132 | 133 | #if LJ_HASFFI 134 | int lj_vm_errno(void) 135 | { 136 | return errno; 137 | } 138 | #endif 139 | 140 | #endif 141 | -------------------------------------------------------------------------------- /src/ljamalg.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** LuaJIT core and libraries amalgamation. 3 | ** Copyright (C) 2005-2022 Mike Pall. See Copyright Notice in luajit.h 4 | */ 5 | 6 | /* 7 | +--------------------------------------------------------------------------+ 8 | | WARNING: Compiling the amalgamation needs a lot of virtual memory | 9 | | (around 300 MB with GCC 4.x)! If you don't have enough physical memory | 10 | | your machine will start swapping to disk and the compile will not finish | 11 | | within a reasonable amount of time. | 12 | | So either compile on a bigger machine or use the non-amalgamated build. | 13 | +--------------------------------------------------------------------------+ 14 | */ 15 | 16 | #define ljamalg_c 17 | #define LUA_CORE 18 | 19 | /* To get the mremap prototype. Must be defined before any system includes. */ 20 | #if defined(__linux__) && !defined(_GNU_SOURCE) 21 | #define _GNU_SOURCE 22 | #endif 23 | 24 | #ifndef WINVER 25 | #define WINVER 0x0501 26 | #endif 27 | 28 | #include "lua.h" 29 | #include "lauxlib.h" 30 | 31 | #include "lj_gc.c" 32 | #include "lj_err.c" 33 | #include "lj_char.c" 34 | #include "lj_bc.c" 35 | #include "lj_obj.c" 36 | #include "lj_str.c" 37 | #include "lj_tab.c" 38 | #include "lj_func.c" 39 | #include "lj_udata.c" 40 | #include "lj_meta.c" 41 | #include "lj_debug.c" 42 | #include "lj_state.c" 43 | #include "lj_dispatch.c" 44 | #include "lj_vmevent.c" 45 | #include "lj_vmmath.c" 46 | #include "lj_strscan.c" 47 | #include "lj_api.c" 48 | #include "lj_lex.c" 49 | #include "lj_parse.c" 50 | #include "lj_bcread.c" 51 | #include "lj_bcwrite.c" 52 | #include "lj_load.c" 53 | #include "lj_ctype.c" 54 | #include "lj_cdata.c" 55 | #include "lj_cconv.c" 56 | #include "lj_ccall.c" 57 | #include "lj_ccallback.c" 58 | #include "lj_carith.c" 59 | #include "lj_clib.c" 60 | #include "lj_cparse.c" 61 | #include "lj_lib.c" 62 | #include "lj_ir.c" 63 | #include "lj_opt_mem.c" 64 | #include "lj_opt_fold.c" 65 | #include "lj_opt_narrow.c" 66 | #include "lj_opt_dce.c" 67 | #include "lj_opt_loop.c" 68 | #include "lj_opt_split.c" 69 | #include "lj_opt_sink.c" 70 | #include "lj_mcode.c" 71 | #include "lj_snap.c" 72 | #include "lj_record.c" 73 | #include "lj_crecord.c" 74 | #include "lj_ffrecord.c" 75 | #include "lj_asm.c" 76 | #include "lj_trace.c" 77 | #include "lj_gdbjit.c" 78 | #include "lj_alloc.c" 79 | 80 | #include "lib_aux.c" 81 | #include "lib_base.c" 82 | #include "lib_math.c" 83 | #include "lib_string.c" 84 | #include "lib_table.c" 85 | #include "lib_io.c" 86 | #include "lib_os.c" 87 | #include "lib_package.c" 88 | #include "lib_debug.c" 89 | #include "lib_bit.c" 90 | #include "lib_jit.c" 91 | #include "lib_ffi.c" 92 | #include "lib_init.c" 93 | 94 | -------------------------------------------------------------------------------- /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-2022 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 | #include 14 | 15 | /* Default path for loading Lua and C modules with require(). */ 16 | #if defined(LUAJIT_PORTABLE_INSTALL) 17 | /* 18 | ** In Windows, any exclamation mark ('!') in the path is replaced by the 19 | ** path of the directory of the executable file of the current process. 20 | ** 21 | ** Modification for lhelper (https://github.com/franko/lhelper.git): 22 | ** Use the exclamation mark ('!') also on unix-like system if the 23 | ** portable option is enabled. 24 | */ 25 | #if defined(_WIN32) 26 | #define LUA_LDIR "!\\lua\\" 27 | #define LUA_CDIR "!\\" 28 | #define LUA_PATH_DEFAULT \ 29 | ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" 30 | #define LUA_CPATH_DEFAULT \ 31 | ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" 32 | #else 33 | #define LUA_LDIR "!/lua/" 34 | #define LUA_CDIR "!/" 35 | #define LUA_PATH_DEFAULT \ 36 | "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" 37 | #define LUA_CPATH_DEFAULT \ 38 | "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" 39 | #endif 40 | #else 41 | /* 42 | ** Note to distribution maintainers: do NOT patch the following lines! 43 | ** Please read ../doc/install.html#distro and pass PREFIX=/usr instead. 44 | */ 45 | #ifndef LUA_MULTILIB 46 | #define LUA_MULTILIB "lib" 47 | #endif 48 | #ifndef LUA_LMULTILIB 49 | #define LUA_LMULTILIB "lib" 50 | #endif 51 | #define LUA_LROOT "/usr/local" 52 | #define LUA_LUADIR "/lua/5.1/" 53 | #define LUA_LJDIR "/luajit-2.0.5/" 54 | 55 | #ifdef LUA_ROOT 56 | #define LUA_JROOT LUA_ROOT 57 | #define LUA_RLDIR LUA_ROOT "/share" LUA_LUADIR 58 | #define LUA_RCDIR LUA_ROOT "/" LUA_MULTILIB LUA_LUADIR 59 | #define LUA_RLPATH ";" LUA_RLDIR "?.lua;" LUA_RLDIR "?/init.lua" 60 | #define LUA_RCPATH ";" LUA_RCDIR "?.so" 61 | #else 62 | #define LUA_JROOT LUA_LROOT 63 | #define LUA_RLPATH 64 | #define LUA_RCPATH 65 | #endif 66 | 67 | #define LUA_JPATH ";" LUA_JROOT "/share" LUA_LJDIR "?.lua" 68 | #define LUA_LLDIR LUA_LROOT "/share" LUA_LUADIR 69 | #define LUA_LCDIR LUA_LROOT "/" LUA_LMULTILIB LUA_LUADIR 70 | #define LUA_LLPATH ";" LUA_LLDIR "?.lua;" LUA_LLDIR "?/init.lua" 71 | #define LUA_LCPATH1 ";" LUA_LCDIR "?.so" 72 | #define LUA_LCPATH2 ";" LUA_LCDIR "loadall.so" 73 | 74 | #define LUA_PATH_DEFAULT "./?.lua" LUA_JPATH LUA_LLPATH LUA_RLPATH 75 | #define LUA_CPATH_DEFAULT "./?.so" LUA_LCPATH1 LUA_RCPATH LUA_LCPATH2 76 | #endif 77 | 78 | /* Environment variable names for path overrides and initialization code. */ 79 | #define LUA_PATH "LUA_PATH" 80 | #define LUA_CPATH "LUA_CPATH" 81 | #define LUA_INIT "LUA_INIT" 82 | 83 | /* Special file system characters. */ 84 | #if defined(_WIN32) 85 | #define LUA_DIRSEP "\\" 86 | #else 87 | #define LUA_DIRSEP "/" 88 | #endif 89 | #define LUA_PATHSEP ";" 90 | #define LUA_PATH_MARK "?" 91 | #define LUA_EXECDIR "!" 92 | #define LUA_IGMARK "-" 93 | #define LUA_PATH_CONFIG \ 94 | LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" \ 95 | LUA_EXECDIR "\n" LUA_IGMARK 96 | 97 | /* Quoting in error messages. */ 98 | #define LUA_QL(x) "'" x "'" 99 | #define LUA_QS LUA_QL("%s") 100 | 101 | /* Various tunables. */ 102 | #define LUAI_MAXSTACK 65500 /* Max. # of stack slots for a thread (<64K). */ 103 | #define LUAI_MAXCSTACK 8000 /* Max. # of stack slots for a C func (<10K). */ 104 | #define LUAI_GCPAUSE 200 /* Pause GC until memory is at 200%. */ 105 | #define LUAI_GCMUL 200 /* Run GC at 200% of allocation speed. */ 106 | #define LUA_MAXCAPTURES 32 /* Max. pattern captures. */ 107 | 108 | /* Compatibility with older library function names. */ 109 | #define LUA_COMPAT_MOD /* OLD: math.mod, NEW: math.fmod */ 110 | #define LUA_COMPAT_GFIND /* OLD: string.gfind, NEW: string.gmatch */ 111 | 112 | /* Configuration for the frontend (the luajit executable). */ 113 | #if defined(luajit_c) 114 | #define LUA_PROGNAME "luajit" /* Fallback frontend name. */ 115 | #define LUA_PROMPT "> " /* Interactive prompt. */ 116 | #define LUA_PROMPT2 ">> " /* Continuation prompt. */ 117 | #define LUA_MAXINPUT 512 /* Max. input line length. */ 118 | #endif 119 | 120 | /* Note: changing the following defines breaks the Lua 5.1 ABI. */ 121 | #define LUA_INTEGER ptrdiff_t 122 | #define LUA_IDSIZE 60 /* Size of lua_Debug.short_src. */ 123 | /* 124 | ** Size of lauxlib and io.* on-stack buffers. Weird workaround to avoid using 125 | ** unreasonable amounts of stack space, but still retain ABI compatibility. 126 | ** Blame Lua for depending on BUFSIZ in the ABI, blame **** for wrecking it. 127 | */ 128 | #define LUAL_BUFFERSIZE (BUFSIZ > 16384 ? 8192 : BUFSIZ) 129 | 130 | /* The following defines are here only for compatibility with luaconf.h 131 | ** from the standard Lua distribution. They must not be changed for LuaJIT. 132 | */ 133 | #define LUA_NUMBER_DOUBLE 134 | #define LUA_NUMBER double 135 | #define LUAI_UACNUMBER double 136 | #define LUA_NUMBER_SCAN "%lf" 137 | #define LUA_NUMBER_FMT "%.14g" 138 | #define lua_number2str(s, n) sprintf((s), LUA_NUMBER_FMT, (n)) 139 | #define LUAI_MAXNUMBER2STR 32 140 | #define LUA_INTFRMLEN "l" 141 | #define LUA_INTFRM_T long 142 | 143 | /* Linkage of public API functions. */ 144 | #if defined(LUA_BUILD_AS_DLL) 145 | #if defined(LUA_CORE) || defined(LUA_LIB) 146 | #define LUA_API __declspec(dllexport) 147 | #else 148 | #define LUA_API __declspec(dllimport) 149 | #endif 150 | #else 151 | #define LUA_API extern 152 | #endif 153 | 154 | #define LUALIB_API LUA_API 155 | 156 | /* Support for internal assertions. */ 157 | #if defined(LUA_USE_ASSERT) || defined(LUA_USE_APICHECK) 158 | #include 159 | #endif 160 | #ifdef LUA_USE_ASSERT 161 | #define lua_assert(x) assert(x) 162 | #endif 163 | #ifdef LUA_USE_APICHECK 164 | #define luai_apicheck(L, o) { (void)L; assert(o); } 165 | #else 166 | #define luai_apicheck(L, o) { (void)L; } 167 | #endif 168 | 169 | #endif 170 | -------------------------------------------------------------------------------- /src/luajit.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** LuaJIT -- a Just-In-Time Compiler for Lua. https://luajit.org/ 3 | ** 4 | ** Copyright (C) 2005-2022 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 LUAJIT_VERSION "LuaJIT 2.0.5" 34 | #define LUAJIT_VERSION_NUM 20005 /* Version 2.0.5 = 02.00.05. */ 35 | #define LUAJIT_VERSION_SYM luaJIT_version_2_0_5 36 | #define LUAJIT_COPYRIGHT "Copyright (C) 2005-2022 Mike Pall" 37 | #define LUAJIT_URL "https://luajit.org/" 38 | 39 | /* Modes for luaJIT_setmode. */ 40 | #define LUAJIT_MODE_MASK 0x00ff 41 | 42 | enum { 43 | LUAJIT_MODE_ENGINE, /* Set mode for whole JIT engine. */ 44 | LUAJIT_MODE_DEBUG, /* Set debug mode (idx = level). */ 45 | 46 | LUAJIT_MODE_FUNC, /* Change mode for a function. */ 47 | LUAJIT_MODE_ALLFUNC, /* Recurse into subroutine protos. */ 48 | LUAJIT_MODE_ALLSUBFUNC, /* Change only the subroutines. */ 49 | 50 | LUAJIT_MODE_TRACE, /* Flush a compiled trace. */ 51 | 52 | LUAJIT_MODE_WRAPCFUNC = 0x10, /* Set wrapper mode for C function calls. */ 53 | 54 | LUAJIT_MODE_MAX 55 | }; 56 | 57 | /* Flags or'ed in to the mode. */ 58 | #define LUAJIT_MODE_OFF 0x0000 /* Turn feature off. */ 59 | #define LUAJIT_MODE_ON 0x0100 /* Turn feature on. */ 60 | #define LUAJIT_MODE_FLUSH 0x0200 /* Flush JIT-compiled code. */ 61 | 62 | /* LuaJIT public C API. */ 63 | 64 | /* Control the JIT engine. */ 65 | LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode); 66 | 67 | /* Enforce (dynamic) linker error for version mismatches. Call from main. */ 68 | LUA_API void LUAJIT_VERSION_SYM(void); 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Standard library header. 3 | ** Copyright (C) 2005-2022 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 | 25 | LUALIB_API int luaopen_base(lua_State *L); 26 | LUALIB_API int luaopen_math(lua_State *L); 27 | LUALIB_API int luaopen_string(lua_State *L); 28 | LUALIB_API int luaopen_table(lua_State *L); 29 | LUALIB_API int luaopen_io(lua_State *L); 30 | LUALIB_API int luaopen_os(lua_State *L); 31 | LUALIB_API int luaopen_package(lua_State *L); 32 | LUALIB_API int luaopen_debug(lua_State *L); 33 | LUALIB_API int luaopen_bit(lua_State *L); 34 | LUALIB_API int luaopen_jit(lua_State *L); 35 | LUALIB_API int luaopen_ffi(lua_State *L); 36 | 37 | LUALIB_API void luaL_openlibs(lua_State *L); 38 | 39 | #ifndef lua_assert 40 | #define lua_assert(x) ((void)0) 41 | #endif 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/meson.build: -------------------------------------------------------------------------------- 1 | lj_arch_test_source = files('lj_arch_test.c') 2 | 3 | if get_option('portable') 4 | jitlib_install_dir = get_option('bindir') / 'lua' / 'jit' 5 | else 6 | jitlib_install_dir = 'share' / ( 'luajit-' + meson.project_version() ) / 'jit' 7 | endif 8 | 9 | subdir('host') 10 | 11 | ljlib_sources = ['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'] 12 | ljcore_sources = ['lj_gc.c', 'lj_err.c', 'lj_char.c', 'lj_bc.c', 'lj_obj.c', 'lj_str.c', 'lj_tab.c', 'lj_func.c', 'lj_udata.c', 'lj_meta.c', 'lj_debug.c', 'lj_state.c', 'lj_dispatch.c', 'lj_vmevent.c', 'lj_vmmath.c', 'lj_strscan.c', 'lj_api.c', 'lj_lex.c', 'lj_parse.c', 'lj_bcread.c', 'lj_bcwrite.c', 'lj_load.c', 'lj_ir.c', 'lj_opt_mem.c', 'lj_opt_fold.c', 'lj_opt_narrow.c', 'lj_opt_dce.c', 'lj_opt_loop.c', 'lj_opt_split.c', 'lj_opt_sink.c', 'lj_mcode.c', 'lj_snap.c', 'lj_record.c', 'lj_crecord.c', 'lj_ffrecord.c', 'lj_asm.c', 'lj_trace.c', 'lj_gdbjit.c', 'lj_ctype.c', 'lj_cdata.c', 'lj_cconv.c', 'lj_ccall.c', 'lj_ccallback.c', 'lj_carith.c', 'lj_clib.c', 'lj_cparse.c', 'lj_lib.c', 'lj_alloc.c', 'lib_aux.c', 'lib_init.c'] 13 | ljmain_sources = ['luajit.c'] 14 | 15 | buildvm_commands = [ 16 | {'mode': 'ffdef', 'output': 'lj_ffdef.h', 'input': ljlib_sources}, 17 | {'mode': 'bcdef', 'output': 'lj_bcdef.h', 'input': ljlib_sources}, 18 | {'mode': 'folddef', 'output': 'lj_folddef.h', 'input': 'lj_opt_fold.c'}, 19 | {'mode': 'recdef', 'output': 'lj_recdef.h', 'input': ljlib_sources}, 20 | {'mode': 'libdef', 'output': 'lj_libdef.h', 'input': ljlib_sources}, 21 | ] 22 | 23 | lj_defines = [ 24 | '-D_FILE_OFFSET_BITS=64', 25 | '-D_LARGEFILE_SOURCE', 26 | '-U_FORTIFY_SOURCE', 27 | '-DLUA_MULTILIB="lib"', 28 | '-DLUA_ROOT="' + get_option('prefix') + '"' 29 | ] 30 | 31 | if host_machine.system() == 'darwin' 32 | lj_defines += '-mmacosx-version-min=10.11' 33 | endif 34 | 35 | if get_option('portable') 36 | lj_defines += '-DLUAJIT_PORTABLE_INSTALL' 37 | endif 38 | 39 | lj_linkargs = [] 40 | if host_machine.system() == 'windows' 41 | ljcore_sources += custom_target('lj_vm.obj', 42 | input : [], 43 | output : 'lj_vm.obj', 44 | command : [buildvm, '-m', 'peobj', '-o', '@OUTPUT@'] 45 | ) 46 | 47 | if get_option('default_library') != 'static' 48 | lj_defines += '-DLUA_BUILD_AS_DLL' 49 | endif 50 | lj_libname = 'lua' + luajit_abiver 51 | lj_libprefix = '' 52 | elif host_machine.system() == 'darwin' 53 | ljcore_sources += custom_target('lj_vm.s', 54 | input : [], 55 | output : 'lj_vm.s', 56 | command : [buildvm, '-m', 'machasm', '-o', '@OUTPUT@'] 57 | ) 58 | lj_libname = 'luajit' 59 | lj_libprefix = 'lib' 60 | lj_linkargs += ['-pagezero_size', '10000', '-image_base', '100000000'] 61 | else 62 | ljcore_sources += custom_target('lj_vm.s', 63 | input : [], 64 | output : 'lj_vm.s', 65 | command : [buildvm, '-m', 'elfasm', '-o', '@OUTPUT@'] 66 | ) 67 | lj_libname = 'luajit' 68 | lj_libprefix = 'lib' 69 | endif 70 | 71 | buildvm_headers = [] 72 | foreach target : buildvm_commands 73 | buildvm_headers += custom_target(target['output'], 74 | input : target['input'], 75 | output : target['output'], 76 | command : [buildvm, '-m', target['mode'], '-o', '@OUTPUT@', '@INPUT@'] 77 | ) 78 | endforeach 79 | 80 | vmdef = custom_target('vmdef.lua', 81 | input : ljlib_sources, 82 | output : 'vmdef.lua', 83 | build_by_default : true, 84 | install: true, 85 | install_dir: jitlib_install_dir, 86 | command : [buildvm, '-m', 'vmdef', '-o', '@OUTPUT@', '@INPUT@'] 87 | ) 88 | 89 | libluajit = library(lj_libname, ljlib_sources + ljcore_sources + buildvm_headers, 90 | include_directories: luajit_source_dir, 91 | c_args: lj_defines, 92 | name_prefix: lj_libprefix, 93 | dependencies: luajit_dependencies, 94 | install: true 95 | ) 96 | 97 | if get_option('app') 98 | luajit = executable('luajit', ljmain_sources, 99 | c_args: lj_defines, 100 | link_args: lj_linkargs, 101 | link_with: libluajit, 102 | include_directories: luajit_source_dir, 103 | dependencies: luajit_dependencies, 104 | install: true 105 | ) 106 | endif 107 | 108 | lua_dep = declare_dependency( 109 | dependencies : luajit_dependencies, 110 | include_directories : luajit_source_dir, 111 | link_with : libluajit, 112 | link_args: lj_linkargs, 113 | ) 114 | 115 | pkg.generate(libluajit, 116 | filebase : 'luajit', 117 | name : 'LuaJIT', 118 | description : 'Just-in-time compiler for Lua', 119 | url : 'http://luajit.org', 120 | ) 121 | 122 | install_headers('lua.h', 'lualib.h', 'lauxlib.h', 'luaconf.h', 'lua.hpp', 'luajit.h') 123 | 124 | subdir('jit') 125 | -------------------------------------------------------------------------------- /src/msvcbuild.bat: -------------------------------------------------------------------------------- 1 | @rem Script to build LuaJIT with MSVC. 2 | @rem Copyright (C) 2005-2022 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 debug emit debug symbols 9 | @rem amalg amalgamated build 10 | @rem static static linkage 11 | 12 | @if not defined INCLUDE goto :FAIL 13 | 14 | @setlocal 15 | @rem Add more debug flags here, e.g. DEBUGCFLAGS=/DLUA_USE_APICHECK 16 | @set DEBUGCFLAGS= 17 | @set LJCOMPILE=cl /nologo /c /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_STDIO_INLINE=__declspec(dllexport)__inline 18 | @set LJLINK=link /nologo 19 | @set LJMT=mt /nologo 20 | @set LJLIB=lib /nologo /nodefaultlib 21 | @set DASMDIR=..\dynasm 22 | @set DASM=%DASMDIR%\dynasm.lua 23 | @set LJDLLNAME=lua51.dll 24 | @set LJLIBNAME=lua51.lib 25 | @set BUILDTYPE=release 26 | @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 27 | 28 | %LJCOMPILE% host\minilua.c 29 | @if errorlevel 1 goto :BAD 30 | %LJLINK% /out:minilua.exe minilua.obj 31 | @if errorlevel 1 goto :BAD 32 | if exist minilua.exe.manifest^ 33 | %LJMT% -manifest minilua.exe.manifest -outputresource:minilua.exe 34 | 35 | @set DASMFLAGS=-D WIN -D JIT -D FFI -D P64 36 | @set LJARCH=x64 37 | @minilua 38 | @if errorlevel 8 goto :X64 39 | @set DASMFLAGS=-D WIN -D JIT -D FFI 40 | @set LJARCH=x86 41 | :X64 42 | minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h vm_x86.dasc 43 | @if errorlevel 1 goto :BAD 44 | 45 | %LJCOMPILE% /I "." /I %DASMDIR% host\buildvm*.c 46 | @if errorlevel 1 goto :BAD 47 | %LJLINK% /out:buildvm.exe buildvm*.obj 48 | @if errorlevel 1 goto :BAD 49 | if exist buildvm.exe.manifest^ 50 | %LJMT% -manifest buildvm.exe.manifest -outputresource:buildvm.exe 51 | 52 | buildvm -m peobj -o lj_vm.obj 53 | @if errorlevel 1 goto :BAD 54 | buildvm -m bcdef -o lj_bcdef.h %ALL_LIB% 55 | @if errorlevel 1 goto :BAD 56 | buildvm -m ffdef -o lj_ffdef.h %ALL_LIB% 57 | @if errorlevel 1 goto :BAD 58 | buildvm -m libdef -o lj_libdef.h %ALL_LIB% 59 | @if errorlevel 1 goto :BAD 60 | buildvm -m recdef -o lj_recdef.h %ALL_LIB% 61 | @if errorlevel 1 goto :BAD 62 | buildvm -m vmdef -o jit\vmdef.lua %ALL_LIB% 63 | @if errorlevel 1 goto :BAD 64 | buildvm -m folddef -o lj_folddef.h lj_opt_fold.c 65 | @if errorlevel 1 goto :BAD 66 | 67 | @if "%1" neq "debug" goto :NODEBUG 68 | @shift 69 | @set BUILDTYPE=debug 70 | @set LJCOMPILE=%LJCOMPILE% /Zi %DEBUGCFLAGS% 71 | :NODEBUG 72 | @set LJLINK=%LJLINK% /%BUILDTYPE% 73 | @if "%1"=="amalg" goto :AMALGDLL 74 | @if "%1"=="static" goto :STATIC 75 | %LJCOMPILE% /MD /DLUA_BUILD_AS_DLL lj_*.c lib_*.c 76 | @if errorlevel 1 goto :BAD 77 | %LJLINK% /DLL /out:%LJDLLNAME% lj_*.obj lib_*.obj 78 | @if errorlevel 1 goto :BAD 79 | @goto :MTDLL 80 | :STATIC 81 | %LJCOMPILE% lj_*.c lib_*.c 82 | @if errorlevel 1 goto :BAD 83 | %LJLIB% /OUT:%LJLIBNAME% lj_*.obj lib_*.obj 84 | @if errorlevel 1 goto :BAD 85 | @goto :MTDLL 86 | :AMALGDLL 87 | %LJCOMPILE% /MD /DLUA_BUILD_AS_DLL ljamalg.c 88 | @if errorlevel 1 goto :BAD 89 | %LJLINK% /DLL /out:%LJDLLNAME% ljamalg.obj lj_vm.obj 90 | @if errorlevel 1 goto :BAD 91 | :MTDLL 92 | if exist %LJDLLNAME%.manifest^ 93 | %LJMT% -manifest %LJDLLNAME%.manifest -outputresource:%LJDLLNAME%;2 94 | 95 | %LJCOMPILE% luajit.c 96 | @if errorlevel 1 goto :BAD 97 | %LJLINK% /out:luajit.exe luajit.obj %LJLIBNAME% 98 | @if errorlevel 1 goto :BAD 99 | if exist luajit.exe.manifest^ 100 | %LJMT% -manifest luajit.exe.manifest -outputresource:luajit.exe 101 | 102 | @del *.obj *.manifest minilua.exe buildvm.exe 103 | @del host\buildvm_arch.h 104 | @del lj_bcdef.h lj_ffdef.h lj_libdef.h lj_recdef.h lj_folddef.h 105 | @echo. 106 | @echo === Successfully built LuaJIT for Windows/%LJARCH% === 107 | 108 | @goto :END 109 | :BAD 110 | @echo. 111 | @echo ******************************************************* 112 | @echo *** Build FAILED -- Please check the error messages *** 113 | @echo ******************************************************* 114 | @goto :END 115 | :FAIL 116 | @echo You must open a "Visual Studio Command Prompt" to run this script 117 | :END 118 | -------------------------------------------------------------------------------- /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 Then cd to this directory and run this script. 6 | 7 | @if not defined INCLUDE goto :FAIL 8 | @if not defined SCE_ORBIS_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 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 64 bit host compiler. 27 | @minilua 28 | @if not errorlevel 8 goto :FAIL 29 | 30 | @set DASMFLAGS=-D P64 -D NO_UNWIND 31 | minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h vm_x86.dasc 32 | @if errorlevel 1 goto :BAD 33 | 34 | %LJCOMPILE% /I "." /I %DASMDIR% -DLUAJIT_TARGET=LUAJIT_ARCH_X64 -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI -DLUAJIT_NO_UNWIND host\buildvm*.c 35 | @if errorlevel 1 goto :BAD 36 | %LJLINK% /out:buildvm.exe buildvm*.obj 37 | @if errorlevel 1 goto :BAD 38 | if exist buildvm.exe.manifest^ 39 | %LJMT% -manifest buildvm.exe.manifest -outputresource:buildvm.exe 40 | 41 | buildvm -m elfasm -o lj_vm.s 42 | @if errorlevel 1 goto :BAD 43 | buildvm -m bcdef -o lj_bcdef.h %ALL_LIB% 44 | @if errorlevel 1 goto :BAD 45 | buildvm -m ffdef -o lj_ffdef.h %ALL_LIB% 46 | @if errorlevel 1 goto :BAD 47 | buildvm -m libdef -o lj_libdef.h %ALL_LIB% 48 | @if errorlevel 1 goto :BAD 49 | buildvm -m recdef -o lj_recdef.h %ALL_LIB% 50 | @if errorlevel 1 goto :BAD 51 | buildvm -m vmdef -o jit\vmdef.lua %ALL_LIB% 52 | @if errorlevel 1 goto :BAD 53 | buildvm -m folddef -o lj_folddef.h lj_opt_fold.c 54 | @if errorlevel 1 goto :BAD 55 | 56 | @rem ---- Cross compiler ---- 57 | @set LJCOMPILE="%SCE_ORBIS_SDK_DIR%\host_tools\bin\orbis-clang" -c -Wall -DLUAJIT_DISABLE_FFI 58 | @set LJLIB="%SCE_ORBIS_SDK_DIR%\host_tools\bin\orbis-ar" rcus 59 | @set INCLUDE="" 60 | 61 | orbis-as -o lj_vm.o lj_vm.s 62 | 63 | @if "%1" neq "debug" goto :NODEBUG 64 | @shift 65 | @set LJCOMPILE=%LJCOMPILE% -g -O0 66 | @set TARGETLIB=libluajitD.a 67 | goto :BUILD 68 | :NODEBUG 69 | @set LJCOMPILE=%LJCOMPILE% -O2 70 | @set TARGETLIB=libluajit.a 71 | :BUILD 72 | del %TARGETLIB% 73 | @if "%1"=="amalg" goto :AMALG 74 | for %%f in (lj_*.c lib_*.c) do ( 75 | %LJCOMPILE% %%f 76 | @if errorlevel 1 goto :BAD 77 | ) 78 | 79 | %LJLIB% %TARGETLIB% lj_*.o lib_*.o 80 | @if errorlevel 1 goto :BAD 81 | @goto :NOAMALG 82 | :AMALG 83 | %LJCOMPILE% ljamalg.c 84 | @if errorlevel 1 goto :BAD 85 | %LJLIB% %TARGETLIB% ljamalg.o lj_vm.o 86 | @if errorlevel 1 goto :BAD 87 | :NOAMALG 88 | 89 | @del *.o *.obj *.manifest minilua.exe buildvm.exe 90 | @echo. 91 | @echo === Successfully built LuaJIT for PS4 === 92 | 93 | @goto :END 94 | :BAD 95 | @echo. 96 | @echo ******************************************************* 97 | @echo *** Build FAILED -- Please check the error messages *** 98 | @echo ******************************************************* 99 | @goto :END 100 | :FAIL 101 | @echo To run this script you must open a "Visual Studio .NET Command Prompt" 102 | @echo (64 bit host compiler). The PS4 Orbis SDK must be installed, too. 103 | :END 104 | -------------------------------------------------------------------------------- /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 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 | %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 35 | @if errorlevel 1 goto :BAD 36 | %LJLINK% /out:buildvm.exe buildvm*.obj 37 | @if errorlevel 1 goto :BAD 38 | if exist buildvm.exe.manifest^ 39 | %LJMT% -manifest buildvm.exe.manifest -outputresource:buildvm.exe 40 | 41 | buildvm -m elfasm -o lj_vm.s 42 | @if errorlevel 1 goto :BAD 43 | buildvm -m bcdef -o lj_bcdef.h %ALL_LIB% 44 | @if errorlevel 1 goto :BAD 45 | buildvm -m ffdef -o lj_ffdef.h %ALL_LIB% 46 | @if errorlevel 1 goto :BAD 47 | buildvm -m libdef -o lj_libdef.h %ALL_LIB% 48 | @if errorlevel 1 goto :BAD 49 | buildvm -m recdef -o lj_recdef.h %ALL_LIB% 50 | @if errorlevel 1 goto :BAD 51 | buildvm -m vmdef -o jit\vmdef.lua %ALL_LIB% 52 | @if errorlevel 1 goto :BAD 53 | buildvm -m folddef -o lj_folddef.h lj_opt_fold.c 54 | @if errorlevel 1 goto :BAD 55 | 56 | @rem ---- Cross compiler ---- 57 | @set LJCOMPILE="%SCE_PSP2_SDK_DIR%\host_tools\build\bin\psp2snc" -c -w -DLUAJIT_DISABLE_FFI -DLUAJIT_USE_SYSMALLOC 58 | @set LJLIB="%SCE_PSP2_SDK_DIR%\host_tools\build\bin\psp2ld32" -r --output= 59 | @set INCLUDE="" 60 | 61 | "%SCE_PSP2_SDK_DIR%\host_tools\build\bin\psp2as" -o lj_vm.o lj_vm.s 62 | 63 | @if "%1" neq "debug" goto :NODEBUG 64 | @shift 65 | @set LJCOMPILE=%LJCOMPILE% -g -O0 66 | @set TARGETLIB=libluajitD.a 67 | goto :BUILD 68 | :NODEBUG 69 | @set LJCOMPILE=%LJCOMPILE% -O2 70 | @set TARGETLIB=libluajit.a 71 | :BUILD 72 | del %TARGETLIB% 73 | 74 | %LJCOMPILE% ljamalg.c 75 | @if errorlevel 1 goto :BAD 76 | %LJLIB%%TARGETLIB% ljamalg.o lj_vm.o 77 | @if errorlevel 1 goto :BAD 78 | 79 | @del *.o *.obj *.manifest minilua.exe buildvm.exe 80 | @echo. 81 | @echo === Successfully built LuaJIT for PS Vita === 82 | 83 | @goto :END 84 | :BAD 85 | @echo. 86 | @echo ******************************************************* 87 | @echo *** Build FAILED -- Please check the error messages *** 88 | @echo ******************************************************* 89 | @goto :END 90 | :FAIL 91 | @echo To run this script you must open a "Visual Studio .NET Command Prompt" 92 | @echo (32 bit host compiler). The PS Vita SDK must be installed, too. 93 | :END 94 | -------------------------------------------------------------------------------- /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 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 | %LJCOMPILE% /I "." /I %DASMDIR% /D_XBOX_VER=200 /DLUAJIT_TARGET=LUAJIT_ARCH_PPC host\buildvm*.c 35 | @if errorlevel 1 goto :BAD 36 | %LJLINK% /out:buildvm.exe buildvm*.obj 37 | @if errorlevel 1 goto :BAD 38 | if exist buildvm.exe.manifest^ 39 | %LJMT% -manifest buildvm.exe.manifest -outputresource:buildvm.exe 40 | 41 | buildvm -m peobj -o lj_vm.obj 42 | @if errorlevel 1 goto :BAD 43 | buildvm -m bcdef -o lj_bcdef.h %ALL_LIB% 44 | @if errorlevel 1 goto :BAD 45 | buildvm -m ffdef -o lj_ffdef.h %ALL_LIB% 46 | @if errorlevel 1 goto :BAD 47 | buildvm -m libdef -o lj_libdef.h %ALL_LIB% 48 | @if errorlevel 1 goto :BAD 49 | buildvm -m recdef -o lj_recdef.h %ALL_LIB% 50 | @if errorlevel 1 goto :BAD 51 | buildvm -m vmdef -o jit\vmdef.lua %ALL_LIB% 52 | @if errorlevel 1 goto :BAD 53 | buildvm -m folddef -o lj_folddef.h lj_opt_fold.c 54 | @if errorlevel 1 goto :BAD 55 | 56 | @rem ---- Cross compiler ---- 57 | @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 58 | @set LJLIB="%XEDK%\bin\win32\lib" /nologo 59 | @set "INCLUDE=%XEDK%\include\xbox" 60 | 61 | @if "%1" neq "debug" goto :NODEBUG 62 | @shift 63 | @set "LJCOMPILE=%LJCOMPILE% /Zi" 64 | :NODEBUG 65 | @if "%1"=="amalg" goto :AMALG 66 | %LJCOMPILE% /DLUA_BUILD_AS_DLL lj_*.c lib_*.c 67 | @if errorlevel 1 goto :BAD 68 | %LJLIB% /OUT:luajit20.lib lj_*.obj lib_*.obj 69 | @if errorlevel 1 goto :BAD 70 | @goto :NOAMALG 71 | :AMALG 72 | %LJCOMPILE% /DLUA_BUILD_AS_DLL ljamalg.c 73 | @if errorlevel 1 goto :BAD 74 | %LJLIB% /OUT:luajit20.lib ljamalg.obj lj_vm.obj 75 | @if errorlevel 1 goto :BAD 76 | :NOAMALG 77 | 78 | @del *.obj *.manifest minilua.exe buildvm.exe 79 | @echo. 80 | @echo === Successfully built LuaJIT for Xbox 360 === 81 | 82 | @goto :END 83 | :BAD 84 | @echo. 85 | @echo ******************************************************* 86 | @echo *** Build FAILED -- Please check the error messages *** 87 | @echo ******************************************************* 88 | @goto :END 89 | :FAIL 90 | @echo To run this script you must open a "Visual Studio .NET Command Prompt" 91 | @echo (32 bit host compiler). The Xbox 360 SDK must be installed, too. 92 | :END 93 | --------------------------------------------------------------------------------