├── .codespell-ignore-words.txt ├── .flake8rc ├── .github ├── actions │ ├── setup-gcovr │ │ ├── README.md │ │ └── action.yml │ ├── setup-linux │ │ ├── README.md │ │ └── action.yml │ ├── setup-macos │ │ ├── README.md │ │ └── action.yml │ ├── setup-sanitizers │ │ ├── README.md │ │ └── action.yml │ ├── setup-valgrind │ │ ├── README.md │ │ └── action.yml │ └── setup │ │ ├── README.md │ │ └── action.yml └── workflows │ ├── avx512-build-testing.yml │ ├── coverage.yml │ ├── exotic-builds-testing.yml │ ├── gnumake-builds-testing.yml │ ├── integration-tarantool-ecosystem.yml │ ├── integration-tarantool.yml │ ├── lint.yml │ ├── sanitizers-testing.yml │ ├── testing.yml │ └── valgrind-testing.yaml ├── .gitignore ├── .luacheckrc ├── CMakeLists.txt ├── COPYRIGHT ├── Makefile.original ├── README ├── cmake ├── CheckUnwindTables.cmake ├── CodeCoverage.cmake ├── CodeSpell.cmake ├── LuaJITUtils.cmake ├── MakeLuaPath.cmake ├── MakeSourceList.cmake ├── SetBuildParallelLevel.cmake ├── SetDynASMFlags.cmake ├── SetTargetFlags.cmake ├── SetVersion.cmake └── cmake_uninstall.cmake.in ├── doc ├── bluequad-print.css ├── bluequad.css ├── changes.html ├── contact.html ├── ext_c_api.html ├── ext_ffi.html ├── ext_ffi_api.html ├── ext_ffi_semantics.html ├── ext_ffi_tutorial.html ├── ext_jit.html ├── ext_profiler.html ├── extensions.html ├── faq.html ├── img │ └── contact.png ├── install.html ├── luajit.html ├── running.html └── status.html ├── dynasm ├── dasm_arm.h ├── dasm_arm.lua ├── dasm_arm64.h ├── dasm_arm64.lua ├── dasm_mips.h ├── dasm_mips.lua ├── dasm_mips64.lua ├── dasm_ppc.h ├── dasm_ppc.lua ├── dasm_proto.h ├── dasm_x64.lua ├── dasm_x86.h ├── dasm_x86.lua └── dynasm.lua ├── etc ├── CMakeLists.txt ├── luajit.1 └── luajit.pc.in ├── src ├── .gitignore ├── CMakeLists.txt ├── Makefile.dep.original ├── Makefile.original ├── host │ ├── .gitignore │ ├── CMakeLists.txt │ ├── README │ ├── buildvm.c │ ├── buildvm.h │ ├── buildvm_asm.c │ ├── buildvm_fold.c │ ├── buildvm_lib.c │ ├── buildvm_libbc.h │ ├── buildvm_peobj.c │ ├── genlibbc.lua │ ├── genminilua.lua │ └── minilua.c ├── jit │ ├── .gitignore │ ├── bc.lua │ ├── bcsave.lua │ ├── dis_arm.lua │ ├── dis_arm64.lua │ ├── dis_arm64be.lua │ ├── dis_mips.lua │ ├── dis_mips64.lua │ ├── dis_mips64el.lua │ ├── dis_mips64r6.lua │ ├── dis_mips64r6el.lua │ ├── dis_mipsel.lua │ ├── dis_ppc.lua │ ├── dis_x64.lua │ ├── dis_x86.lua │ ├── dump.lua │ ├── p.lua │ ├── v.lua │ └── zone.lua ├── lauxlib.h ├── lib_aux.c ├── lib_base.c ├── lib_bit.c ├── lib_debug.c ├── lib_ffi.c ├── lib_init.c ├── lib_io.c ├── lib_jit.c ├── lib_math.c ├── lib_misc.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_asm.c ├── lj_asm.h ├── lj_asm_arm.h ├── lj_asm_arm64.h ├── lj_asm_mips.h ├── lj_asm_ppc.h ├── lj_asm_x86.h ├── lj_assert.c ├── lj_bc.c ├── lj_bc.h ├── lj_bcdump.h ├── lj_bcread.c ├── lj_bcwrite.c ├── lj_buf.c ├── lj_buf.h ├── lj_carith.c ├── lj_carith.h ├── lj_ccall.c ├── lj_ccall.h ├── lj_ccallback.c ├── lj_ccallback.h ├── lj_cconv.c ├── lj_cconv.h ├── lj_cdata.c ├── lj_cdata.h ├── lj_char.c ├── lj_char.h ├── lj_clib.c ├── lj_clib.h ├── lj_cparse.c ├── lj_cparse.h ├── lj_crecord.c ├── lj_crecord.h ├── lj_ctype.c ├── lj_ctype.h ├── lj_debug.c ├── lj_debug.h ├── lj_def.h ├── lj_dispatch.c ├── lj_dispatch.h ├── lj_emit_arm.h ├── lj_emit_arm64.h ├── lj_emit_mips.h ├── lj_emit_ppc.h ├── lj_emit_x86.h ├── lj_err.c ├── lj_err.h ├── lj_errmsg.h ├── lj_extra.supp ├── 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_mapi.c ├── lj_mcode.c ├── lj_mcode.h ├── lj_memprof.c ├── lj_memprof.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_profile.c ├── lj_profile.h ├── lj_profile_timer.c ├── lj_profile_timer.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_strfmt.c ├── lj_strfmt.h ├── lj_strfmt_num.c ├── lj_strscan.c ├── lj_strscan.h ├── lj_symtab.c ├── lj_symtab.h ├── lj_sysprof.c ├── lj_sysprof.h ├── lj_tab.c ├── lj_tab.h ├── lj_target.h ├── lj_target_arm.h ├── lj_target_arm64.h ├── lj_target_mips.h ├── lj_target_ppc.h ├── lj_target_x86.h ├── lj_trace.c ├── lj_trace.h ├── lj_traceerr.h ├── lj_udata.c ├── lj_udata.h ├── lj_utils.h ├── lj_utils_leb128.c ├── lj_vm.h ├── lj_vmevent.c ├── lj_vmevent.h ├── lj_vmmath.c ├── lj_wbuf.c ├── lj_wbuf.h ├── ljamalg.c ├── lmisclib.h ├── lua.h ├── lua.hpp ├── luaconf.h ├── luajit-gdb.py ├── luajit.c ├── luajit.h ├── luajit_lldb.py ├── lualib.h ├── msvcbuild.bat ├── ps4build.bat ├── psvitabuild.bat ├── vm_arm.dasc ├── vm_arm64.dasc ├── vm_mips.dasc ├── vm_mips64.dasc ├── vm_ppc.dasc ├── vm_x64.dasc ├── vm_x86.dasc ├── xb1build.bat └── xedkbuild.bat ├── test ├── CMakeLists.txt ├── LuaJIT-tests │ ├── CMakeLists.txt │ ├── README.md │ ├── bc │ │ ├── constov.lua │ │ └── index │ ├── common │ │ ├── expect_error.lua │ │ ├── fails.lua │ │ ├── ffi │ │ │ ├── checkfail.lua │ │ │ └── checktypes.lua │ │ ├── ffi_util.inc │ │ └── test_runner_canary.lua │ ├── computations.lua │ ├── index │ ├── lang │ │ ├── andor.lua │ │ ├── api_call.lua │ │ ├── assignment.lua │ │ ├── catch_cpp.lua │ │ ├── catch_wrap.lua │ │ ├── compare.lua │ │ ├── compare_nan.lua │ │ ├── concat.lua │ │ ├── constant │ │ │ ├── index │ │ │ ├── number.lua │ │ │ └── table.lua │ │ ├── deep_recursion.lua │ │ ├── dualnum.lua │ │ ├── for.lua │ │ ├── gc.lua │ │ ├── gc_debug.lua │ │ ├── gc_stack.lua │ │ ├── gc_step.lua │ │ ├── goto.lua │ │ ├── hook_active.lua │ │ ├── hook_line.lua │ │ ├── hook_top.lua │ │ ├── index │ │ ├── length.lua │ │ ├── lightud.lua │ │ ├── meta │ │ │ ├── arith.lua │ │ │ ├── arith_jit.lua │ │ │ ├── call.lua │ │ │ ├── cat.lua │ │ │ ├── comp.lua │ │ │ ├── comp_jit.lua │ │ │ ├── debuginfo.lua │ │ │ ├── eq.lua │ │ │ ├── eq_jit.lua │ │ │ ├── framegap.lua │ │ │ ├── index │ │ │ ├── index.lua │ │ │ ├── len.lua │ │ │ ├── newindex.lua │ │ │ └── nomm.lua │ │ ├── modulo.lua │ │ ├── parse_comp.lua │ │ ├── parse_esc.lua │ │ ├── parse_misc.lua │ │ ├── self.lua │ │ ├── stackov.lua │ │ ├── stackov_c.lua │ │ ├── table.lua │ │ ├── tail_recursion.lua │ │ ├── upvalue │ │ │ ├── closure.lua │ │ │ └── index │ │ ├── vararg_jit.lua │ │ └── wbarrier.lua │ ├── lib │ │ ├── base │ │ │ ├── assert.lua │ │ │ ├── error.lua │ │ │ ├── getfenv.lua │ │ │ ├── getsetmetatable.lua │ │ │ ├── index │ │ │ ├── ipairs.lua │ │ │ ├── next.lua │ │ │ ├── pairs.lua │ │ │ ├── pcall_jit.lua │ │ │ ├── select.lua │ │ │ ├── tonumber_scan.lua │ │ │ ├── tonumber_tostring.lua │ │ │ └── xpcall_jit.lua │ │ ├── bit.lua │ │ ├── contents.lua │ │ ├── coroutine │ │ │ ├── index │ │ │ ├── traceback.lua │ │ │ └── yield.lua │ │ ├── ffi │ │ │ ├── bit64.lua │ │ │ ├── cdata_var.lua │ │ │ ├── copy_fill.lua │ │ │ ├── err.lua │ │ │ ├── ffi_arith_ptr.lua │ │ │ ├── ffi_bitfield.lua │ │ │ ├── ffi_call.lua │ │ │ ├── ffi_callback.lua │ │ │ ├── ffi_const.lua │ │ │ ├── ffi_convert.lua │ │ │ ├── ffi_enum.lua │ │ │ ├── ffi_gcstep_recursive.lua │ │ │ ├── ffi_jit_arith.lua │ │ │ ├── ffi_jit_call.lua │ │ │ ├── ffi_jit_conv.lua │ │ │ ├── ffi_lex_number.lua │ │ │ ├── ffi_metatype.lua │ │ │ ├── ffi_new.lua │ │ │ ├── ffi_parse_array.lua │ │ │ ├── ffi_parse_basic.lua │ │ │ ├── ffi_parse_cdef.lua │ │ │ ├── ffi_parse_struct.lua │ │ │ ├── index │ │ │ ├── istype.lua │ │ │ ├── jit_array.lua │ │ │ ├── jit_complex.lua │ │ │ ├── jit_misc.lua │ │ │ ├── jit_struct.lua │ │ │ ├── meta_tostring.lua │ │ │ ├── redir.lua │ │ │ └── type_punning.lua │ │ ├── index │ │ ├── math │ │ │ ├── abs.lua │ │ │ ├── constants.lua │ │ │ ├── index │ │ │ └── random.lua │ │ ├── string │ │ │ ├── byte.lua │ │ │ ├── char.lua │ │ │ ├── dump.lua │ │ │ ├── format │ │ │ │ ├── index │ │ │ │ └── num.lua │ │ │ ├── index │ │ │ ├── len.lua │ │ │ ├── lower_upper.lua │ │ │ ├── metatable.lua │ │ │ ├── multiple_functions.lua │ │ │ ├── rep.lua │ │ │ ├── reverse.lua │ │ │ └── sub.lua │ │ └── table │ │ │ ├── concat.lua │ │ │ ├── index │ │ │ ├── insert.lua │ │ │ ├── misc.lua │ │ │ ├── new.lua │ │ │ ├── pack.lua │ │ │ ├── remove.lua │ │ │ └── sort.lua │ ├── opt │ │ ├── dse │ │ │ ├── array.lua │ │ │ ├── field.lua │ │ │ └── index │ │ ├── fold │ │ │ ├── index │ │ │ └── kfold.lua │ │ ├── fuse.lua │ │ ├── fwd │ │ │ ├── hrefk_rollback.lua │ │ │ ├── index │ │ │ ├── tnew_tdup.lua │ │ │ └── upval.lua │ │ ├── index │ │ ├── loop │ │ │ ├── index │ │ │ └── unroll.lua │ │ ├── mem │ │ │ ├── alias_alloc.lua │ │ │ └── index │ │ └── sink │ │ │ ├── alloc.lua │ │ │ ├── ffi.lua │ │ │ ├── ffi_nosink.lua │ │ │ ├── index │ │ │ └── nosink.lua │ ├── src │ │ ├── CMakeLists.txt │ │ ├── libcpptest.cpp │ │ └── libctest.c │ ├── sysdep │ │ ├── ffi_include_gtk.lua │ │ ├── ffi_include_std.lua │ │ ├── ffi_lib_c.lua │ │ └── ffi_lib_z.lua │ ├── test.lua │ ├── trace │ │ ├── exit_frame.lua │ │ ├── exit_growstack.lua │ │ ├── exit_jfuncf.lua │ │ ├── gc.lua │ │ ├── gc64_slot_revival.lua │ │ ├── hook_norecord.lua │ │ ├── hook_record.lua │ │ ├── index │ │ ├── jit_flush.lua │ │ ├── phi │ │ │ ├── conv.lua │ │ │ ├── copyspill.lua │ │ │ ├── index │ │ │ ├── ref.lua │ │ │ └── rotate.lua │ │ ├── snap.lua │ │ ├── stack_purge.lua │ │ ├── stitch.lua │ │ ├── tcall_base.lua │ │ ├── tcall_loop.lua │ │ ├── unordered_jit.lua │ │ └── wbarrier.lua │ └── unportable │ │ ├── ffi_arith_int64.lua │ │ └── math_special.lua ├── PUC-Rio-Lua-5.1-tests │ ├── CMakeLists.txt │ ├── README │ ├── all.lua │ ├── api.lua │ ├── attrib.lua │ ├── big.lua │ ├── calls.lua │ ├── checktable.lua │ ├── closure.lua │ ├── code.lua │ ├── constructs.lua │ ├── db.lua │ ├── errors.lua │ ├── etc │ │ ├── ltests.c │ │ └── ltests.h │ ├── events.lua │ ├── files.lua │ ├── gc.lua │ ├── libs │ │ ├── CMakeLists.txt │ │ ├── lib1.c │ │ ├── lib11.c │ │ ├── lib2.c │ │ └── lib21.c │ ├── literals.lua │ ├── locals.lua │ ├── main.lua │ ├── math.lua │ ├── nextvar.lua │ ├── pm.lua │ ├── sort.lua │ ├── strings.lua │ ├── vararg.lua │ └── verybig.lua ├── cmake │ ├── AddTestLib.cmake │ ├── GetLibCVersion.cmake │ ├── GetLinuxDistro.cmake │ └── LibRealPath.cmake ├── lua-Harness-tests │ ├── 000-sanity.t │ ├── 001-if.t │ ├── 002-table.t │ ├── 011-while.t │ ├── 012-repeat.t │ ├── 014-fornum.t │ ├── 015-forlist.t │ ├── 090-tap.t │ ├── 091-profile.t │ ├── 101-boolean.t │ ├── 102-function.t │ ├── 103-nil.t │ ├── 104-number.t │ ├── 105-string.t │ ├── 106-table.t │ ├── 107-thread.t │ ├── 108-userdata.t │ ├── 200-examples.t │ ├── 201-assign.t │ ├── 202-expr.t │ ├── 203-lexico.t │ ├── 204-grammar.t │ ├── 211-scope.t │ ├── 212-function.t │ ├── 213-closure.t │ ├── 214-coroutine.t │ ├── 221-table.t │ ├── 222-constructor.t │ ├── 223-iterator.t │ ├── 231-metatable.t │ ├── 232-object.t │ ├── 241-standalone.t │ ├── 242-luac.t │ ├── 301-basic.t │ ├── 303-package.t │ ├── 304-string.t │ ├── 305-utf8.t │ ├── 306-table.t │ ├── 307-math.t │ ├── 308-io.t │ ├── 309-os.t │ ├── 310-debug.t │ ├── 311-bit32.t │ ├── 314-regex.t │ ├── 320-stdin.t │ ├── 401-bitop.t │ ├── 402-ffi.t │ ├── 403-jit.t │ ├── 404-ext.t │ ├── 411-luajit.t │ ├── CMakeLists.txt │ ├── lexico52 │ │ └── lexico.t │ ├── lexico53 │ │ ├── boolean.t │ │ ├── function.t │ │ ├── lexico.t │ │ ├── nil.t │ │ ├── number.t │ │ ├── string.t │ │ ├── table.t │ │ ├── thread.t │ │ ├── userdata.t │ │ └── utf8.t │ ├── lexico54 │ │ ├── lexico.t │ │ ├── metatable.t │ │ └── utf8.t │ ├── lexicojit │ │ ├── basic.t │ │ ├── ext.t │ │ └── lexico.t │ ├── profile.lua │ ├── profile_lua51.lua │ ├── profile_lua51_strict.lua │ ├── profile_lua52.lua │ ├── profile_lua52_strict.lua │ ├── profile_lua53.lua │ ├── profile_lua53_noconv.lua │ ├── profile_lua53_strict.lua │ ├── profile_lua54.lua │ ├── profile_lua54_noconv.lua │ ├── profile_lua54_strict.lua │ ├── profile_luajit20.lua │ ├── profile_luajit20_compat52.lua │ ├── profile_luajit21.lua │ ├── profile_luajit21_compat52.lua │ ├── profile_openresty.lua │ ├── profile_ravi.lua │ ├── profile_tarantool.lua │ ├── profile_tiny_fork.lua │ ├── rx_captures │ ├── rx_charclass │ ├── rx_metachars │ └── test_assertion.lua ├── luajit-test-init.lua ├── tarantool-c-tests │ ├── CMakeLists.txt │ ├── README.md │ ├── fix-yield-c-hook-script.lua │ ├── fix-yield-c-hook.test.c │ ├── gh-8594-sysprof-ffunc-crash.test.c │ ├── lj-1087-vm-handler-call.test.c │ ├── lj-1168-unmarked-finalizer-tab.test.c │ ├── lj-49-bad-lightuserdata.test.c │ ├── lj-549-lua-load.test.c │ ├── lj-881-fix-lua-concat.test.c │ ├── lj-962-premature-stack-overflow.test.c │ ├── lj-991-fix-finalizer-error-handler-init.test.c │ ├── misclib-getmetrics-capi-script.lua │ ├── misclib-getmetrics-capi.test.c │ ├── misclib-sysprof-capi-script.lua │ ├── misclib-sysprof-capi.test.c │ ├── test.c │ ├── test.h │ ├── unit-tap.test.c │ └── utils.h └── tarantool-tests │ ├── CMakeLists.txt │ ├── bc-jit-unpatching.test.lua │ ├── c-library-path-length.test.lua │ ├── ffi-ccall-arm64-fp-convention.test.lua │ ├── ffi-ccall │ ├── CMakeLists.txt │ └── libfficcall.c │ ├── ffi-tabov.test.lua │ ├── fix-argv-handling.test.lua │ ├── fix-argv-handling │ ├── CMakeLists.txt │ ├── execlib.c │ └── mynewstate.c │ ├── fix-argv2ctype-cts-L-init.test.lua │ ├── fix-argv2ctype-cts-L-init │ └── script.lua │ ├── fix-binary-number-parsing.test.lua │ ├── fix-bit-shift-dualnum.test.lua │ ├── fix-bit-shift-generation.test.lua │ ├── fix-bit-shift-generation │ ├── CMakeLists.txt │ └── libtestbitshift.c │ ├── fix-cdata-concat.test.lua │ ├── fix-dangling-reference-to-ctype.test.lua │ ├── fix-emit-rma.test.lua │ ├── fix-ff-select-recording.test.lua │ ├── fix-fold-simplify-conv-sext.test.lua │ ├── fix-gc-setupvalue.test.lua │ ├── fix-jit-dump-ir-conv.test.lua │ ├── fix-mips64-spare-side-exit-patching.test.lua │ ├── fix-recording-bc-varg-used-in-select.test.lua │ ├── fix-slot-check-for-mm-record.test.lua │ ├── fix-slots-overflow-for-varg-record.test.lua │ ├── fix-stack-alloc-on-trace-exit.test.lua │ ├── gh-3196-incorrect-string-length.test.lua │ ├── gh-4199-gc64-fuse.test.lua │ ├── gh-4427-ffi-sandwich.test.lua │ ├── gh-4427-ffi-sandwich │ ├── CMakeLists.txt │ ├── libsandwich.c │ └── script.lua │ ├── gh-4476-fix-string-find-recording.test.lua │ ├── gh-4773-tonumber-fail-on-NUL-char.test.lua │ ├── gh-6065-jit-library-smoke-tests.test.lua │ ├── gh-6084-missed-carg1-in-bctsetr-fallback.test.lua │ ├── gh-6096-external-unwinding-on-arm64.test.lua │ ├── gh-6098-fix-side-exit-patching-on-arm64.test.lua │ ├── gh-6098-fix-side-exit-patching-on-arm64 │ ├── CMakeLists.txt │ └── libproxy.c │ ├── gh-6163-min-max.test.lua │ ├── gh-6189-cur_L.test.lua │ ├── gh-6189-cur_L │ ├── CMakeLists.txt │ └── libcur_L.c │ ├── gh-6227-bytecode-allocator-for-comparisons.test.lua │ ├── gh-6371-string-char-no-arg.test.lua │ ├── gh-6782-stitching-in-vmevent-handler.test.lua │ ├── gh-6976-narrowing-of-unary-minus.test.lua │ ├── gh-7745-oom-on-trace.test.lua │ ├── lj-1004-oom-error-frame.test.lua │ ├── lj-1004-oom-error-frame │ ├── CMakeLists.txt │ └── testoomframe.c │ ├── lj-1024-varg-maxslot.test.lua │ ├── lj-1025-tsetm-maxslot.test.lua │ ├── lj-1031-asm-head-side-base-reg.test.lua │ ├── lj-1033-fix-parsing-predict-next.test.lua │ ├── lj-1034-tabov-error-frame.test.lua │ ├── lj-1043-asm-fload.test.lua │ ├── lj-1046-fix-bc-varg-recording.test.lua │ ├── lj-1052-unsink-with-irfl-tab-nomm.test.lua │ ├── lj-1054-fix-incorrect-pc-value-in-predict-next.test.lua │ ├── lj-1066-fix-cur_L-after-coroutine-resume.test.lua │ ├── lj-1066-fix-cur_L-after-coroutine-resume │ ├── CMakeLists.txt │ └── libcur_L_coroutine.c │ ├── lj-1069-newref-nan-key.test.lua │ ├── lj-1079-fix-64-bitshift-folds.test.lua │ ├── lj-1082-min-max-0-commutative.test.lua │ ├── lj-1083-missing-tostring-coercion-in-select.test.lua │ ├── lj-1094-ir-chain-dce.test.lua │ ├── lj-1108-fix-dangling-reference-to-ctype.test.lua │ ├── lj-1114-ffi-pragma-pack.test.lua │ ├── lj-1116-redzones-checks.test.lua │ ├── lj-1117-fuse-across-newref.test.lua │ ├── lj-1117-fuse-across-table-clear.test.lua │ ├── lj-1128-double-ir-newref-on-restore-sunk.test.lua │ ├── lj-1128-table-new-opt-tnew.test.lua │ ├── lj-1132-bad-snap-refs.test.lua │ ├── lj-1133-fwd-href-hrefk-alias.test.lua │ ├── lj-1134-hotside-jit-off.test.lua │ ├── lj-1147-fstore-null-meta.test.lua │ ├── lj-1149-g-number-formating-bufov.test.lua │ ├── lj-1164-record-meta-concat-varg-pcall.test.lua │ ├── lj-1166-error-stitch-oom-ir-buff.test.lua │ ├── lj-1166-error-stitch-oom-snap-buff.test.lua │ ├── lj-1166-error-stitch-table-bump.test.lua │ ├── lj-1168-unmarked-finalizer-tab.test.lua │ ├── lj-1169-down-rec-side.test.lua │ ├── lj-1172-debug-handling-ref.test.lua │ ├── lj-1173-frame-limit-lower-frame.test.lua │ ├── lj-1193-out-of-bounds-snap-restoredata.test.lua │ ├── lj-1194-abc-hoisting.test.lua │ ├── lj-1203-limit-format-elements.test.lua │ ├── lj-1224-fix-cdata-arith-ptr.test.lua │ ├── lj-1224-fix-cdata-arith-side.test.lua │ ├── lj-1224-fix-cdata-arith-side │ └── script.lua │ ├── lj-1224-fix-cdata-arith.test.lua │ ├── lj-1224-fix-cdata-arith │ └── script.lua │ ├── lj-1226-fix-predict-next.test.lua │ ├── lj-1232-fix-enum-tostring.test.lua │ ├── lj-1234-err-in-record-concat.test.lua │ ├── lj-1244-missing-phi-carg.test.lua │ ├── lj-1247-fin-tab-rehashing-on-trace.test.lua │ ├── lj-1252-missing-bit64-coercion.test.lua │ ├── lj-1262-fix-limit-narrow-conv-backprop.test.lua │ ├── lj-1273-dualnum-bit-coercion.test.lua │ ├── lj-1279-incorrect-recording-getmetatable.test.lua │ ├── lj-128-fix-union-init.test.lua │ ├── lj-1295-bad-renames-for-sunk-values.test.lua │ ├── lj-1298-oom-on-concat-recording.test.lua │ ├── lj-1304-close-profile-dump-with-0-samples.test.lua │ ├── lj-1329-getfenv-setfenv-negative.test.lua │ ├── lj-1345-flushing-trace-twice.test.lua │ ├── lj-1350-fix-gc-finalizer-pressure.test.lua │ ├── lj-350-sload-typecheck.test.lua │ ├── lj-351-print-tostring-number.test.lua │ ├── lj-351-print-tostring-number │ └── script.lua │ ├── lj-356-ir-khash-non-string-obj.test.lua │ ├── lj-357-arm64-hrefk.test.lua │ ├── lj-362-mips64-href-delay-slot-side-exit.test.lua │ ├── lj-366-strtab-correct-size.test.lua │ ├── lj-375-ir-bufput-signed-char.test.lua │ ├── lj-378-string-format-c-null-char.test.lua │ ├── lj-408-tonumber-cdata-record.test.lua │ ├── lj-416-xor-before-jcc.test.lua │ ├── lj-416-xor-before-jcc │ ├── CMakeLists.txt │ └── testxor.c │ ├── lj-418-assert-any-type.test.lua │ ├── lj-426-arm64-incorrect-check-closed-uv.test.lua │ ├── lj-430-maxirconst.test.lua │ ├── lj-438-arm64-constant-rematerialization.test.lua │ ├── lj-445-fix-memory-probing-allocator.test.lua │ ├── lj-463-os-date-oom.test.lua │ ├── lj-494-table-chain-infinite-loop.test.lua │ ├── lj-505-fold-no-strref-for-ptrdiff.test.lua │ ├── lj-509-debug-getinfo-arguments-check.test.lua │ ├── lj-512-profiler-hook-finalizers.test.lua │ ├── lj-522-fix-dlerror-return-null.test.lua │ ├── lj-522-fix-dlerror-return-null │ ├── CMakeLists.txt │ ├── mydlerror.c │ └── script.lua │ ├── lj-524-fold-conv-respect-src-irt.test.lua │ ├── lj-528-tonumber-0.test.lua │ ├── lj-549-bytecode-loader.test.lua │ ├── lj-549-bytecode-loader │ ├── CMakeLists.txt │ └── script.lua │ ├── lj-551-bytecode-c-broken-macro.test.lua │ ├── lj-551-bytecode-c-broken-macro │ ├── CMakeLists.txt │ └── script.lua │ ├── lj-556-fix-loop-realignment.test.lua │ ├── lj-567-1176-print-nyi-names.test.lua │ ├── lj-574-overflow-unpack.test.lua │ ├── lj-584-bad-renames-for-sunk-values.test.lua │ ├── lj-586-debug-non-string-error.test.lua │ ├── lj-601-fix-gc-finderrfunc.test.lua │ ├── lj-601-fix-gc-finderrfunc │ ├── CMakeLists.txt │ └── mixcframe.c │ ├── lj-603-err-snap-restore.test.lua │ ├── lj-611-gc64-inherit-frame-slot-orig.test.lua │ ├── lj-611-gc64-inherit-frame-slot.test.lua │ ├── lj-624-jloop-snapshot-pc.test.lua │ ├── lj-671-arm64-assert-after-mremap.test.lua │ ├── lj-672-cdata-allocation-recording.test.lua │ ├── lj-684-pow-inconsistencies.test.lua │ ├── lj-688-snap-ir-rename.test.lua │ ├── lj-690-concat-tail-call.test.lua │ ├── lj-695-ffi-vararg-call.test.lua │ ├── lj-698-arm-pcall-panic.test.lua │ ├── lj-704-bc-varg-use-def.test.lua │ ├── lj-720-errors-before-stitch.test.lua │ ├── lj-726-profile-flush-close.test.lua │ ├── lj-727-lightuserdata-itern.test.lua │ ├── lj-727-lightuserdata-itern │ ├── CMakeLists.txt │ └── lightuserdata.c │ ├── lj-735-io-close-on-closed-file.test.lua │ ├── lj-736-BC_UCLO-triggers-infinite-loop.test.lua │ ├── lj-737-snap-use-def-upvalues.test.lua │ ├── lj-745-ffi-typeinfo-dead-names.test.lua │ ├── lj-762-pcall-no-arg.test.lua │ ├── lj-783-fold--0.test.lua │ ├── lj-784-cse-ref-base-over-retf.test.lua │ ├── lj-788-limit-exponents-range.test.lua │ ├── lj-791-fold-bufhdr-append.test.lua │ ├── lj-792-hrefk-table-clear.test.lua │ ├── lj-794-abc-fold-constants.test.lua │ ├── lj-802-panic-at-mcode-protfail.test.lua │ ├── lj-802-panic-at-mcode-protfail │ ├── CMakeLists.txt │ ├── mymprotect.c │ └── script.lua │ ├── lj-812-too-long-string-separator.test.lua │ ├── lj-819-fix-missing-uclo.test.lua │ ├── lj-833-fold-conv-from-num.test.lua │ ├── lj-839-concat-recording.test.lua │ ├── lj-840-gc64-fix-hrefk-optimization.test.lua │ ├── lj-859-math-ceil-sign.test.lua │ ├── lj-861-ctype-attributes.test.lua │ ├── lj-864-varg-rec-base-offset.test.lua │ ├── lj-865-cross-generation-mach-o-file.test.lua │ ├── lj-9-pow-inconsistencies.test.lua │ ├── lj-906-fix-err-mem.test.lua │ ├── lj-913-stackoverflow-stitched-trace.test.lua │ ├── lj-918-fma-numerical-accuracy-jit.test.lua │ ├── lj-918-fma-numerical-accuracy.test.lua │ ├── lj-918-fma-optimization.test.lua │ ├── lj-920-fix-dangling-reference-to-ctype.test.lua │ ├── lj-928-int-min-negation.test.lua │ ├── lj-946-print-errors-from-gc-fin-custom.test.lua │ ├── lj-946-print-errors-from-gc-fin-default.test.lua │ ├── lj-946-print-errors-from-gc-fin-default │ └── script.lua │ ├── lj-962-stack-overflow-report.test.lua │ ├── lj-962-stack-overflow-report │ └── script.lua │ ├── lj-980-load-fwd-after-table-rehash.test.lua │ ├── lj-981-folding-0.test.lua │ ├── lj-994-instable-types-during-loop-unroll.test.lua │ ├── lj-flush-on-trace.test.lua │ ├── lj-flush-on-trace │ ├── CMakeLists.txt │ ├── libflush.c │ └── script.lua │ ├── mark-conv-non-weak.test.lua │ ├── math-modf.test.lua │ ├── misclib-getmetrics-lapi.test.lua │ ├── or-144-gc64-asmref-l.test.lua │ ├── or-232-unsink-64-kptr.test.lua │ ├── or-94-arm64-ir-ahuvload-bool.test.lua │ ├── profilers │ ├── gh-5688-tool-cli-flag.test.lua │ ├── gh-5813-resolving-of-c-symbols.test.lua │ ├── gh-5813-resolving-of-c-symbols │ │ ├── both │ │ │ ├── CMakeLists.txt │ │ │ └── resboth.c │ │ ├── gnuhash │ │ │ ├── CMakeLists.txt │ │ │ └── resgnuhash.c │ │ ├── hash │ │ │ ├── CMakeLists.txt │ │ │ └── reshash.c │ │ └── stripped │ │ │ ├── CMakeLists.txt │ │ │ └── resstripped.c │ ├── gh-5994-memprof-human-readable.test.lua │ ├── gh-7264-add-proto-trace-sysprof-default.test.lua │ ├── gh-9217-profile-parsers-error-handling.test.lua │ ├── misclib-memprof-lapi-default-file.test.lua │ ├── misclib-memprof-lapi-disabled.test.lua │ ├── misclib-memprof-lapi.test.lua │ ├── misclib-sysprof-lapi-disabled.test.lua │ ├── misclib-sysprof-lapi.test.lua │ └── tools-utils-avl.test.lua │ ├── tap.lua │ ├── tonumber-negative-non-decimal-base.test.lua │ ├── unit-jit-parse-abort.test.lua │ ├── unit-jit-parse.test.lua │ └── utils │ ├── CMakeLists.txt │ ├── allocinject.c │ ├── exec.lua │ ├── frontend.lua │ ├── gc.lua │ ├── init.lua │ ├── jit │ ├── const.lua │ ├── generators.lua │ ├── init.lua │ └── parse.lua │ └── tools.lua └── tools ├── CMakeLists.txt ├── memprof.lua ├── memprof ├── humanize.lua ├── parse.lua └── process.lua ├── sysprof.lua ├── sysprof └── parse.lua └── utils ├── avl.lua ├── bufread.lua ├── evread.lua └── symtab.lua /.codespell-ignore-words.txt: -------------------------------------------------------------------------------- 1 | fal 2 | fpr 3 | isnt 4 | nd 5 | tru 6 | -------------------------------------------------------------------------------- /.flake8rc: -------------------------------------------------------------------------------- 1 | [flake8] 2 | extend-ignore = 3 | # XXX: Suppress F821, since we have autogenerated names for 4 | # 'ptr' type complements in luajit_lldb.py. 5 | F821 6 | -------------------------------------------------------------------------------- /.github/actions/setup-gcovr/README.md: -------------------------------------------------------------------------------- 1 | # Setup gcovr 2 | 3 | Action setups the gcovr tool on Linux runners. 4 | 5 | ## How to use Github Action from Github workflow 6 | 7 | Add the following code to the running steps before LuaJIT configuration: 8 | ``` 9 | - uses: ./.github/actions/setup-gcovr 10 | ``` 11 | -------------------------------------------------------------------------------- /.github/actions/setup-gcovr/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup gcovr 2 | description: Setup gcovr 3 | runs: 4 | using: composite 5 | steps: 6 | - name: Install gcovr and dependencies 7 | run: | 8 | pip3 install gcovr==6.0 9 | shell: bash 10 | -------------------------------------------------------------------------------- /.github/actions/setup-linux/README.md: -------------------------------------------------------------------------------- 1 | # Setup environment on Linux 2 | 3 | Action setups the environment on Linux runners (install requirements, setup the 4 | workflow environment, etc). 5 | 6 | ## How to use Github Action from Github workflow 7 | 8 | Add the following code to the running steps before LuaJIT configuration: 9 | ``` 10 | - uses: ./.github/actions/setup-linux 11 | if: ${{ matrix.OS == 'Linux' }} 12 | ``` 13 | -------------------------------------------------------------------------------- /.github/actions/setup-linux/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup CI environment on Linux 2 | description: Common part to tweak Linux CI runner environment 3 | runs: 4 | using: composite 5 | steps: 6 | - name: Setup CI environment 7 | uses: ./.github/actions/setup 8 | - name: Set CMAKE_BUILD_PARALLEL_LEVEL 9 | run: | 10 | # Set CMAKE_BUILD_PARALLEL_LEVEL environment variable to 11 | # limit the number of parallel jobs for build/test step. 12 | NPROC=$(nproc) 13 | echo CMAKE_BUILD_PARALLEL_LEVEL=$(($NPROC + 1)) | tee -a $GITHUB_ENV 14 | shell: bash 15 | - name: Install build and test dependencies 16 | run: | 17 | apt -y update 18 | apt -y install cmake gcc make ninja-build perl 19 | shell: bash 20 | -------------------------------------------------------------------------------- /.github/actions/setup-macos/README.md: -------------------------------------------------------------------------------- 1 | # Setup environment on macOS 2 | 3 | Action setups the environment on macOS runners (install requirements, setup the 4 | workflow environment, etc). 5 | 6 | ## How to use Github Action from Github workflow 7 | 8 | Add the following code to the running steps before LuaJIT configuration: 9 | ``` 10 | - uses: ./.github/actions/setup-macos 11 | if: ${{ matrix.OS == 'macOS' }} 12 | ``` 13 | -------------------------------------------------------------------------------- /.github/actions/setup-sanitizers/README.md: -------------------------------------------------------------------------------- 1 | # Setup environment for sanitizers on Linux 2 | 3 | Action setups the environment on Linux runners (install requirements, setup the 4 | workflow environment, etc) for testing with sanitizers enabled. 5 | 6 | ## How to use Github Action from Github workflow 7 | 8 | Add the following code to the running steps before LuaJIT configuration: 9 | ``` 10 | - uses: ./.github/actions/setup-sanitizers 11 | if: ${{ matrix.OS == 'Linux' }} 12 | ``` 13 | -------------------------------------------------------------------------------- /.github/actions/setup-valgrind/README.md: -------------------------------------------------------------------------------- 1 | # Setup environment for Valgrind on Linux 2 | 3 | Action setups the environment on Linux runners (install requirements, setup the 4 | workflow environment, etc) for testing with Valgrind. 5 | 6 | ## How to use Github Action from Github workflow 7 | 8 | Add the following code to the running steps before LuaJIT configuration: 9 | ``` 10 | - uses: ./.github/actions/setup-valgrind 11 | if: ${{ matrix.OS == 'Linux' }} 12 | ``` -------------------------------------------------------------------------------- /.github/actions/setup-valgrind/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup CI environment with Valgrind on Linux 2 | description: Extend setup-linux with Valgrind installation 3 | 4 | runs: 5 | using: composite 6 | steps: 7 | - name: Setup CI environment (Linux) 8 | uses: ./.github/actions/setup-linux 9 | - name: Install Valgrind 10 | run: | 11 | apt -y install valgrind 12 | shell: bash 13 | -------------------------------------------------------------------------------- /.github/actions/setup/README.md: -------------------------------------------------------------------------------- 1 | # Setup environment 2 | 3 | Action setups the environment to $GITHUB_ENV as suggested in 4 | [Github Action documentation](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable). 5 | It is used as a common environment setup for the different testing workflows. 6 | 7 | ## How to use Github Action from Github workflow 8 | 9 | Add the following code to the running steps or OS-specific GitHub Actions after 10 | checkout step is finished: 11 | ``` 12 | - uses: ./.github/actions/setup 13 | ``` 14 | -------------------------------------------------------------------------------- /.github/actions/setup/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup CI environment 2 | description: Common part to tweak CI runner environment 3 | runs: 4 | using: composite 5 | steps: 6 | - run: | 7 | # Set BUILDDIR environment variable to specify LuaJIT 8 | # build directory. 9 | echo BUILDDIR=${{ runner.temp }}/build-${{ github.run_id }} | tee -a $GITHUB_ENV 10 | shell: bash 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.[oa] 2 | *.so* 3 | *.obj 4 | *.lib 5 | *.exp 6 | *.dll 7 | *.exe 8 | *.manifest 9 | *.dmp 10 | *.swp 11 | .tags 12 | 13 | # CMake generated artefacts 14 | .ninja_deps 15 | .ninja_log 16 | CMakeCache.txt 17 | CMakeFiles 18 | CTestTestfile.cmake 19 | Makefile 20 | Testing 21 | build 22 | build.ninja 23 | cmake_install.cmake 24 | cmake_uninstall.cmake 25 | compile_commands.json 26 | install_manifest.txt 27 | luajit-parse-memprof 28 | luajit-parse-sysprof 29 | luajit.pc 30 | *.c_test 31 | -------------------------------------------------------------------------------- /.luacheckrc: -------------------------------------------------------------------------------- 1 | -- Use the default LuaJIT globals. 2 | std = 'luajit' 3 | -- This fork also introduces a new global for misc API namespace. 4 | read_globals = { 'misc' } 5 | 6 | max_code_line_length = 80 7 | max_comment_line_length = 66 8 | 9 | -- The `_TARANTOOL` global is often used for skip condition 10 | -- checks in tests. 11 | files['test/tarantool-tests/'] = { 12 | read_globals = {'_TARANTOOL'}, 13 | } 14 | 15 | -- These files are inherited from the vanilla LuaJIT or different 16 | -- test suites and need to be coherent with the upstream. 17 | exclude_files = { 18 | 'dynasm/', 19 | 'src/', 20 | 'test/LuaJIT-tests/', 21 | 'test/PUC-Rio-Lua-5.1-tests/', 22 | 'test/lua-Harness-tests/', 23 | } 24 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | README for LuaJIT 2.1.0-beta3 2 | ----------------------------- 3 | 4 | LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language. 5 | 6 | Project Homepage: http://luajit.org/ 7 | 8 | LuaJIT is Copyright (C) 2005-2017 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 | -------------------------------------------------------------------------------- /cmake/SetBuildParallelLevel.cmake: -------------------------------------------------------------------------------- 1 | # The function sets the given variable in a parent scope to a 2 | # number to CMAKE_BUILD_PARALLEL_LEVEL environment variable if it 3 | # is set. Otherwise the number of CPU cores is get via 4 | # ProcessorCount CMake builtin module. If the ProcessorCount fails 5 | # to determine the number of cores (i.e. yields 0), the given 6 | # variable defaults to 1. 7 | 8 | function(SetBuildParallelLevel outvar) 9 | set(JOBS $ENV{CMAKE_BUILD_PARALLEL_LEVEL}) 10 | if(NOT JOBS) 11 | set(JOBS 1) 12 | include(ProcessorCount) 13 | ProcessorCount(NPROC) 14 | if(NOT NPROC EQUAL 0) 15 | set(JOBS ${NPROC}) 16 | endif() 17 | endif() 18 | set(${outvar} ${JOBS} PARENT_SCOPE) 19 | message(STATUS "[SetBuildParallelLevel] ${outvar} is ${JOBS}") 20 | endfunction() 21 | -------------------------------------------------------------------------------- /cmake/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") 2 | message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") 3 | endif() 4 | 5 | # XXX: This loop removes only entries from install_manifest.txt, 6 | # but do nothing for the directories created while installation. 7 | # Honestly, the recipe is awful, but is better than nothing. 8 | file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) 9 | string(REGEX REPLACE "\n" ";" files "${files}") 10 | foreach(file ${files}) 11 | message(STATUS "Uninstalling $ENV{DESTDIR}${file}") 12 | if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 13 | execute_process( 14 | COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}" 15 | RESULT_VARIABLE REMOVE_RC 16 | OUTPUT_QUIET 17 | ) 18 | if(NOT "${REMOVE_RC}" STREQUAL 0) 19 | message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") 20 | endif() 21 | else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 22 | message(STATUS "File $ENV{DESTDIR}${file} does not exist.") 23 | endif() 24 | endforeach() 25 | -------------------------------------------------------------------------------- /doc/img/contact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tarantool/luajit/24d66ccea14b1292422a103b38dbc8c971e05937/doc/img/contact.png -------------------------------------------------------------------------------- /dynasm/dasm_mips64.lua: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | -- DynASM MIPS64 module. 3 | -- 4 | -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. 5 | -- See dynasm.lua for full copyright notice. 6 | ------------------------------------------------------------------------------ 7 | -- This module just sets 64 bit mode for the combined MIPS/MIPS64 module. 8 | -- All the interesting stuff is there. 9 | ------------------------------------------------------------------------------ 10 | 11 | mips64 = true -- Using a global is an ugly, but effective solution. 12 | return require("dasm_mips") 13 | -------------------------------------------------------------------------------- /dynasm/dasm_x64.lua: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | -- DynASM x64 module. 3 | -- 4 | -- Copyright (C) 2005-2017 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/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Building supplementary materials for LuaJIT. 2 | 3 | set(LUAJIT_PC_PREFIX ${CMAKE_INSTALL_PREFIX}) 4 | if(CMAKE_LIBRARY_ARCHITECTURE) 5 | set(LUAJIT_PC_MULTILIB "lib/${CMAKE_LIBRARY_ARCHITECTURE}") 6 | else() 7 | set(LUAJIT_PC_MULTILIB "lib") 8 | endif() 9 | 10 | configure_file(luajit.pc.in luajit.pc @ONLY ESCAPE_QUOTES) 11 | 12 | install(FILES 13 | luajit.1 14 | DESTINATION share/man/man1 15 | PERMISSIONS 16 | OWNER_READ OWNER_WRITE 17 | GROUP_READ 18 | WORLD_READ 19 | COMPONENT luajit 20 | ) 21 | 22 | install(FILES 23 | ${CMAKE_CURRENT_BINARY_DIR}/luajit.pc 24 | DESTINATION lib/pkgconfig 25 | PERMISSIONS 26 | OWNER_READ OWNER_WRITE 27 | GROUP_READ 28 | WORLD_READ 29 | COMPONENT luajit 30 | ) 31 | -------------------------------------------------------------------------------- /etc/luajit.pc.in: -------------------------------------------------------------------------------- 1 | # Package information for LuaJIT to be used by pkg-config. 2 | majver=2 3 | minver=1 4 | relver=0 5 | version=${majver}.${minver}.${relver}-beta3 6 | abiver=5.1 7 | 8 | prefix=@LUAJIT_PC_PREFIX@ 9 | multilib=@LUAJIT_PC_MULTILIB@ 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: http://luajit.org 21 | Version: ${version} 22 | Requires: 23 | Libs: -L${libdir} -l${libname} 24 | Libs.private: -Wl,-E -lm -ldl 25 | Cflags: -I${includedir} 26 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | luajit 2 | lj_bcdef.h 3 | lj_ffdef.h 4 | lj_libdef.h 5 | lj_recdef.h 6 | lj_folddef.h 7 | lj_vm.[sS] 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/jit/.gitignore: -------------------------------------------------------------------------------- 1 | vmdef.lua 2 | *.lua.c 3 | -------------------------------------------------------------------------------- /src/jit/dis_arm64be.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------- 2 | -- LuaJIT ARM64BE disassembler wrapper module. 3 | -- 4 | -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. 5 | -- Released under the MIT license. See Copyright Notice in luajit.h 6 | ---------------------------------------------------------------------------- 7 | -- ARM64 instructions are always little-endian. So just forward to the 8 | -- common ARM64 disassembler module. All the interesting stuff is there. 9 | ------------------------------------------------------------------------------ 10 | 11 | return require((string.match(..., ".*%.") or "").."dis_arm64") 12 | 13 | -------------------------------------------------------------------------------- /src/jit/dis_mips64.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------- 2 | -- LuaJIT MIPS64 disassembler wrapper module. 3 | -- 4 | -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. 5 | -- Released under the MIT license. See Copyright Notice in luajit.h 6 | ---------------------------------------------------------------------------- 7 | -- This module just exports the big-endian functions from the 8 | -- MIPS disassembler module. All the interesting stuff is there. 9 | ------------------------------------------------------------------------------ 10 | 11 | local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") 12 | return { 13 | create = dis_mips.create, 14 | disass = dis_mips.disass, 15 | regname = dis_mips.regname 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/jit/dis_mips64el.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------- 2 | -- LuaJIT MIPS64EL disassembler wrapper module. 3 | -- 4 | -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. 5 | -- Released under the MIT license. See Copyright Notice in luajit.h 6 | ---------------------------------------------------------------------------- 7 | -- This module just exports the little-endian functions from the 8 | -- MIPS disassembler module. All the interesting stuff is there. 9 | ------------------------------------------------------------------------------ 10 | 11 | local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") 12 | return { 13 | create = dis_mips.create_el, 14 | disass = dis_mips.disass_el, 15 | regname = dis_mips.regname 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/jit/dis_mips64r6.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------- 2 | -- LuaJIT MIPS64R6 disassembler wrapper module. 3 | -- 4 | -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. 5 | -- Released under the MIT license. See Copyright Notice in luajit.h 6 | ---------------------------------------------------------------------------- 7 | -- This module just exports the r6 big-endian functions from the 8 | -- MIPS disassembler module. All the interesting stuff is there. 9 | ------------------------------------------------------------------------------ 10 | 11 | local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") 12 | return { 13 | create = dis_mips.create_r6, 14 | disass = dis_mips.disass_r6, 15 | regname = dis_mips.regname 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/jit/dis_mips64r6el.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------- 2 | -- LuaJIT MIPS64R6EL disassembler wrapper module. 3 | -- 4 | -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. 5 | -- Released under the MIT license. See Copyright Notice in luajit.h 6 | ---------------------------------------------------------------------------- 7 | -- This module just exports the r6 little-endian functions from the 8 | -- MIPS disassembler module. All the interesting stuff is there. 9 | ------------------------------------------------------------------------------ 10 | 11 | local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") 12 | return { 13 | create = dis_mips.create_r6_el, 14 | disass = dis_mips.disass_r6_el, 15 | regname = dis_mips.regname 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/jit/dis_mipsel.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------- 2 | -- LuaJIT MIPSEL disassembler wrapper module. 3 | -- 4 | -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. 5 | -- Released under the MIT license. See Copyright Notice in luajit.h 6 | ---------------------------------------------------------------------------- 7 | -- This module just exports the little-endian functions from the 8 | -- MIPS disassembler module. All the interesting stuff is there. 9 | ------------------------------------------------------------------------------ 10 | 11 | local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") 12 | return { 13 | create = dis_mips.create_el, 14 | disass = dis_mips.disass_el, 15 | regname = dis_mips.regname 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/jit/dis_x64.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------- 2 | -- LuaJIT x64 disassembler wrapper module. 3 | -- 4 | -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. 5 | -- Released under the MIT license. See Copyright Notice in luajit.h 6 | ---------------------------------------------------------------------------- 7 | -- This module just exports the 64 bit functions from the combined 8 | -- x86/x64 disassembler module. All the interesting stuff is there. 9 | ------------------------------------------------------------------------------ 10 | 11 | local dis_x86 = require((string.match(..., ".*%.") or "").."dis_x86") 12 | return { 13 | create = dis_x86.create64, 14 | disass = dis_x86.disass64, 15 | regname = dis_x86.regname64 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/jit/zone.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------- 2 | -- LuaJIT profiler zones. 3 | -- 4 | -- Copyright (C) 2005-2017 Mike Pall. All rights reserved. 5 | -- Released under the MIT license. See Copyright Notice in luajit.h 6 | ---------------------------------------------------------------------------- 7 | -- 8 | -- This module implements a simple hierarchical zone model. 9 | -- 10 | -- Example usage: 11 | -- 12 | -- local zone = require("jit.zone") 13 | -- zone("AI") 14 | -- ... 15 | -- zone("A*") 16 | -- ... 17 | -- print(zone:get()) --> "A*" 18 | -- ... 19 | -- zone() 20 | -- ... 21 | -- print(zone:get()) --> "AI" 22 | -- ... 23 | -- zone() 24 | -- 25 | ---------------------------------------------------------------------------- 26 | 27 | local remove = table.remove 28 | 29 | return setmetatable({ 30 | flush = function(t) 31 | for i=#t,1,-1 do t[i] = nil end 32 | end, 33 | get = function(t) 34 | return t[#t] 35 | end 36 | }, { 37 | __call = function(t, zone) 38 | if zone then 39 | t[#t+1] = zone 40 | else 41 | return (assert(remove(t), "empty zone stack")) 42 | end 43 | end 44 | }) 45 | 46 | -------------------------------------------------------------------------------- /src/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_asm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** IR assembler (SSA IR -> machine code). 3 | ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h 4 | */ 5 | 6 | #ifndef _LJ_ASM_H 7 | #define _LJ_ASM_H 8 | 9 | #include "lj_jit.h" 10 | 11 | #if LJ_HASJIT 12 | LJ_FUNC void lj_asm_trace(jit_State *J, GCtrace *T); 13 | LJ_FUNC void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, 14 | MCode *target); 15 | #endif 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/lj_assert.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** Internal assertions. 3 | ** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h 4 | */ 5 | 6 | #define lj_assert_c 7 | #define LUA_CORE 8 | 9 | #if defined(LUA_USE_ASSERT) || defined(LUA_USE_APICHECK) 10 | 11 | #include 12 | 13 | #include "lj_obj.h" 14 | 15 | void lj_assert_fail(global_State *g, const char *file, int line, 16 | const char *func, const char *fmt, ...) 17 | { 18 | va_list argp; 19 | va_start(argp, fmt); 20 | fprintf(stderr, "LuaJIT ASSERT %s:%d: %s: ", file, line, func); 21 | vfprintf(stderr, fmt, argp); 22 | fputc('\n', stderr); 23 | va_end(argp); 24 | UNUSED(g); /* May be NULL. TODO: optionally dump state. */ 25 | abort(); 26 | } 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/lj_bc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** Bytecode instruction modes. 3 | ** Copyright (C) 2005-2017 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_ccallback.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** FFI C callback handling. 3 | ** Copyright (C) 2005-2017 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_clib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** FFI C library loader. 3 | ** Copyright (C) 2005-2017 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_extra.supp: -------------------------------------------------------------------------------- 1 | # Valgrind suppression file maintained by the Tarantool team. 2 | 3 | # Missed from the original suppression file. 4 | # Unaligned access to the string, see for the details. 5 | { 6 | Optimized string compare 7 | Memcheck:Addr4 8 | fun:lj_getu32 9 | fun:str_fastcmp 10 | } 11 | 12 | # Missed from the original suppression file. 13 | # `lj_str_cmp()` may read up to 3 extra bytes from the end of the 14 | # string. It is OK due to the aligned allocations. 15 | { 16 | Optimized string compare 17 | Memcheck:Cond 18 | fun:lj_str_cmp 19 | } 20 | -------------------------------------------------------------------------------- /src/lj_ff.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Fast function IDs. 3 | ** Copyright (C) 2005-2017 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-2017 Mike Pall. See Copyright Notice in luajit.h 4 | */ 5 | 6 | #ifndef _LJ_FFRECORD_H 7 | #define _LJ_FFRECORD_H 8 | 9 | #include "lj_obj.h" 10 | #include "lj_jit.h" 11 | 12 | #if LJ_HASJIT 13 | /* Data used by handlers to record a fast function. */ 14 | typedef struct RecordFFData { 15 | TValue *argv; /* Runtime argument values. */ 16 | ptrdiff_t nres; /* Number of returned results (defaults to 1). */ 17 | uint32_t data; /* Per-ffid auxiliary data (opcode, literal etc.). */ 18 | } RecordFFData; 19 | 20 | LJ_FUNC int32_t lj_ffrecord_select_mode(jit_State *J, TRef tr, TValue *tv); 21 | LJ_FUNC void lj_ffrecord_func(jit_State *J); 22 | #endif 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/lj_func.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Function handling (prototypes, functions and upvalues). 3 | ** Copyright (C) 2005-2017 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_gdbjit.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Client for the GDB JIT API. 3 | ** Copyright (C) 2005-2017 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_mcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Machine code management. 3 | ** Copyright (C) 2005-2017 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_parse.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Lua parser (source code -> bytecode). 3 | ** Copyright (C) 2005-2017 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_profile.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Low-overhead profiling. 3 | ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h 4 | */ 5 | 6 | #ifndef _LJ_PROFILE_H 7 | #define _LJ_PROFILE_H 8 | 9 | #include "lj_obj.h" 10 | 11 | #if LJ_HASPROFILE 12 | 13 | LJ_FUNC void LJ_FASTCALL lj_profile_interpreter(lua_State *L); 14 | #if !LJ_PROFILE_SIGPROF 15 | LJ_FUNC void LJ_FASTCALL lj_profile_hook_enter(global_State *g); 16 | LJ_FUNC void LJ_FASTCALL lj_profile_hook_leave(global_State *g); 17 | #endif 18 | 19 | #endif 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/lj_snap.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Snapshot handling. 3 | ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h 4 | */ 5 | 6 | #ifndef _LJ_SNAP_H 7 | #define _LJ_SNAP_H 8 | 9 | #include "lj_obj.h" 10 | #include "lj_jit.h" 11 | 12 | #if LJ_HASJIT 13 | LJ_FUNC void lj_snap_add(jit_State *J); 14 | LJ_FUNC void lj_snap_purge(jit_State *J); 15 | LJ_FUNC void lj_snap_shrink(jit_State *J); 16 | LJ_FUNC IRIns *lj_snap_regspmap(jit_State *J, GCtrace *T, SnapNo snapno, 17 | IRIns *ir); 18 | LJ_FUNC void lj_snap_replay(jit_State *J, GCtrace *T); 19 | LJ_FUNC const BCIns *lj_snap_restore(jit_State *J, void *exptr); 20 | LJ_FUNC void lj_snap_grow_buf_(jit_State *J, MSize need); 21 | LJ_FUNC void lj_snap_grow_map_(jit_State *J, MSize need); 22 | 23 | static LJ_AINLINE void lj_snap_grow_buf(jit_State *J, MSize need) 24 | { 25 | if (LJ_UNLIKELY(need > J->sizesnap)) lj_snap_grow_buf_(J, need); 26 | } 27 | 28 | static LJ_AINLINE void lj_snap_grow_map(jit_State *J, MSize need) 29 | { 30 | if (LJ_UNLIKELY(need > J->sizesnapmap)) lj_snap_grow_map_(J, need); 31 | } 32 | 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/lj_str.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** String handling. 3 | ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h 4 | */ 5 | 6 | #ifndef _LJ_STR_H 7 | #define _LJ_STR_H 8 | 9 | #include 10 | 11 | #include "lj_obj.h" 12 | 13 | /* String helpers. */ 14 | LJ_FUNC int32_t LJ_FASTCALL lj_str_cmp(GCstr *a, GCstr *b); 15 | LJ_FUNC const char *lj_str_find(const char *s, const char *f, 16 | MSize slen, MSize flen); 17 | LJ_FUNC int lj_str_haspattern(GCstr *s); 18 | 19 | /* String interning. */ 20 | LJ_FUNC void lj_str_resize(lua_State *L, MSize newmask); 21 | LJ_FUNCA GCstr *lj_str_new(lua_State *L, const char *str, size_t len); 22 | LJ_FUNC void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s); 23 | 24 | #define lj_str_newz(L, s) (lj_str_new(L, s, strlen(s))) 25 | #define lj_str_newlit(L, s) (lj_str_new(L, "" s, sizeof(s)-1)) 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/lj_udata.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Userdata handling. 3 | ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h 4 | */ 5 | 6 | #ifndef _LJ_UDATA_H 7 | #define _LJ_UDATA_H 8 | 9 | #include "lj_obj.h" 10 | 11 | LJ_FUNC GCudata *lj_udata_new(lua_State *L, MSize sz, GCtab *env); 12 | LJ_FUNC void LJ_FASTCALL lj_udata_free(global_State *g, GCudata *ud); 13 | #if LJ_64 14 | LJ_FUNC void * LJ_FASTCALL lj_lightud_intern(lua_State *L, void *p); 15 | #endif 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/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 | #include "lmisclib.h" 9 | } 10 | 11 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/bc/constov.lua: -------------------------------------------------------------------------------- 1 | 2 | do --- float 3 | local t = { "local x\n" } 4 | for i=2,65537 do t[i] = "x="..i..".5\n" end 5 | assert(loadstring(table.concat(t)) ~= nil) 6 | t[65538] = "x=65538.5" 7 | assert(loadstring(table.concat(t)) == nil) 8 | end 9 | 10 | do --- int 11 | local t = { "local x\n" } 12 | for i=2,65537 do t[i] = "x='"..i.."'\n" end 13 | assert(loadstring(table.concat(t)) ~= nil) 14 | t[65538] = "x='65538'" 15 | assert(loadstring(table.concat(t)) == nil) 16 | end 17 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/bc/index: -------------------------------------------------------------------------------- 1 | constov.lua +slow 2 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/common/expect_error.lua: -------------------------------------------------------------------------------- 1 | return function(f, msg) 2 | local ok, err = pcall(f) 3 | if ok then error("error check unexpectedly succeeded", 2) end 4 | if msg then 5 | if type(err) ~= "string" then 6 | error("error check failed with "..tostring(err), 2) 7 | end 8 | local line, err2 = string.match(err, ":(%d*): (.*)") 9 | if err2 ~= msg then 10 | if err2:gsub(" got no value", " got nil") == msg then 11 | return 12 | end 13 | error("error check failed with "..err, 2) 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/common/fails.lua: -------------------------------------------------------------------------------- 1 | return function(f, ...) 2 | if pcall(f, ...) ~= false then error("failure expected", 2) end 3 | end 4 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/common/ffi/checkfail.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | -- Checker that takes an array of strings that should represent 4 | -- different invalid CTypes (a more common pattern). Also, the 5 | -- second argument may be also the `loadstring` function to check 6 | -- invalid literals or `ffi.cdef` to check invalid C definitions. 7 | return function(t, f) 8 | f = f or ffi.typeof 9 | for i=1,1e9 do 10 | local tp = t[i] 11 | if not tp then break end 12 | assert(pcall(f, tp) == false, tp) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/common/ffi/checktypes.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | -- Checker that takes an array with the following triplets: 4 | -- 1) `sizeof()` for the given C type to be checked. 5 | -- 2) `alignof()` for the given C type to be checked. 6 | -- 3) String representing the C type. 7 | return function(t) 8 | for i=1,1e9,3 do 9 | local tp = t[i+2] 10 | if not tp then break end 11 | local id = ffi.typeof(tp) 12 | assert(ffi.sizeof(id) == t[i], tp) 13 | assert(ffi.alignof(id) == t[i+1], tp) 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/common/ffi_util.inc: -------------------------------------------------------------------------------- 1 | -- This should be turned into a proper module and not use globals. 2 | -- Or combined into a generiv test utility module. With FFI 3 | -- functionality turned off, if the FFI module is not built-in. 4 | 5 | local ffi = require("ffi") 6 | 7 | local incroot = os.getenv("INCROOT") or "/usr/include" 8 | local cdefs = os.getenv("CDEFS") or "" 9 | 10 | function include(name) 11 | local flags = ffi.abi("32bit") and "-m32" or "-m64" 12 | if string.sub(name, 1, 1) ~= "/" then name = incroot.."/"..name end 13 | local fp = assert(io.popen("cc -E -P "..flags.." "..cdefs.." "..name)) 14 | local s = fp:read("*a") 15 | fp:close() 16 | ffi.cdef(s) 17 | end 18 | 19 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/common/test_runner_canary.lua: -------------------------------------------------------------------------------- 1 | return "canary is alive" 2 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/index: -------------------------------------------------------------------------------- 1 | lang 2 | lib 3 | bc +luajit>=2 4 | computations.lua 5 | trace +jit 6 | opt +jit 7 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/assignment.lua: -------------------------------------------------------------------------------- 1 | local assert = assert 2 | 3 | do --- local 4 | local a, b, c 5 | a, b, c = 0, 1 6 | assert(a == 0) 7 | assert(b == 1) 8 | assert(c == nil) 9 | a, b = a+1, b+1, a+b 10 | assert(a == 1) 11 | assert(b == 2) 12 | a, b, c = 0 13 | assert(a == 0) 14 | assert(b == nil) 15 | assert(c == nil) 16 | end 17 | 18 | do --- global !private_G 19 | a, b, c = 0, 1 20 | assert(a == 0) 21 | assert(b == 1) 22 | assert(c == nil) 23 | a, b = a+1, b+1, a+b 24 | assert(a == 1) 25 | assert(b == 2) 26 | a, b, c = 0 27 | assert(a == 0) 28 | assert(b == nil) 29 | assert(c == nil) 30 | end 31 | 32 | do --- local lhs in key on lhs 33 | local a = {} 34 | local i = 3 35 | i, a[i] = i+1, 20 36 | assert(i == 4) 37 | assert(a[3] == 20) 38 | end 39 | 40 | do --- global lhs in key on lhs !private_G 41 | a = {} 42 | i = 3 43 | i, a[i] = i+1, 20 44 | assert(i == 4) 45 | assert(a[3] == 20) 46 | end 47 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/constant/index: -------------------------------------------------------------------------------- 1 | number.lua 2 | table.lua 3 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/constant/number.lua: -------------------------------------------------------------------------------- 1 | do --- exp 2 | assert(1e5 == 100000) 3 | assert(1e+5 == 100000) 4 | assert(1e-5 == 0.00001) 5 | end 6 | 7 | do --- hex exp +hexfloat !lex 8 | assert(0xe+9 == 23) 9 | assert(0xep9 == 7168) 10 | assert(0xep+9 == 7168) 11 | assert(0xep-9 == 0.02734375) 12 | end 13 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/constant/table.lua: -------------------------------------------------------------------------------- 1 | 2 | do --- tnew 3 | local a = nil 4 | local b = {} 5 | local t = {[true] = a, [false] = b or 1} 6 | assert(t[true] == nil) 7 | assert(t[false] == b) 8 | end 9 | 10 | do --- tdup 11 | local b = {} 12 | local t = {[true] = nil, [false] = b or 1} 13 | assert(t[true] == nil) 14 | assert(t[false] == b) 15 | end 16 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/deep_recursion.lua: -------------------------------------------------------------------------------- 1 | do --- Recursion sum. 2 | local function sum(n) 3 | if n == 1 then return 1 end 4 | return n + sum(n-1) 5 | end 6 | assert(sum(200) == 20100) 7 | end 8 | 9 | do --- Recursion wiht pcall. 10 | local pcall = pcall 11 | local tr1 12 | local x = 0 13 | function tr1(n) 14 | if n <= 0 then return end 15 | x = x + 1 16 | return pcall(tr1, n-1) 17 | end 18 | assert(tr1(200) == true and x == 200) 19 | end 20 | 21 | do --- Recursion fibonacci. 22 | local function fib(n) 23 | if n < 2 then return 1 end 24 | return fib(n-2) + fib(n-1) 25 | end 26 | assert(fib(15) == 987) 27 | end 28 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/dualnum.lua: -------------------------------------------------------------------------------- 1 | -- Test LuaJIT Dualnum mode behaviour. 2 | 3 | do --- Positive overflow. 4 | local x = 0 5 | for _ = 2147483446, 2147483647, 2 do x = x + 1 end 6 | assert(x == 101) 7 | end 8 | 9 | do --- Negative overflow. 10 | local x = 0 11 | for _ = -2147483447, -2147483648, -2 do x = x + 1 end 12 | assert(x == 101) 13 | end 14 | 15 | do --- SLOAD with number to integer conversion. 16 | local k = 1 17 | local a, b, c = 1/k, 20/k, 1/k 18 | for _ = 1, 20 do 19 | for _ = a, b, c do end 20 | end 21 | end 22 | 23 | do --- min/max correctness. 24 | local function fmin(a, b) 25 | for _ = 1, 100 do a = math.min(a, b) end 26 | return a 27 | end 28 | local function fmax(a, b) 29 | for _ = 1, 100 do a = math.max(a, b) end 30 | return a 31 | end 32 | assert(fmin(1, 3) == 1) 33 | assert(fmin(3, 1) == 1) 34 | assert(fmin(-1, 3) == -1) 35 | assert(fmin(3, -1) == -1) 36 | assert(fmin(-1, -3) == -3) 37 | assert(fmin(-3, -1) == -3) 38 | assert(fmax(1, 3) == 3) 39 | assert(fmax(3, 1) == 3) 40 | assert(fmax(-1, 3) == 3) 41 | assert(fmax(3, -1) == 3) 42 | assert(fmax(-1, -3) == -1) 43 | assert(fmax(-3, -1) == -1) 44 | end 45 | 46 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/for.lua: -------------------------------------------------------------------------------- 1 | do --- direction 2 | local a,b,c = 10,1,-1 3 | for i=1,20 do 4 | if c == -1 then 5 | a,b,c = 1,10,1 6 | else 7 | a,b,c = 10,1,-1 8 | end 9 | local x = 0 10 | for i=a,b,c do for j=1,10 do end x=x+1 end 11 | assert(x == 10) 12 | end 13 | end 14 | 15 | do --- coerce to integer at 13 16 | local n = 1 17 | local x = 0 18 | for i=1,20 do 19 | for j=n,100 do x = x + 1 end 20 | if i == 13 then n = "2" end 21 | end 22 | assert(x == 1993) 23 | end 24 | 25 | do --- coerce to integer at 10 26 | local n = 1 27 | local x = 0 28 | for i=1,20 do 29 | for j=n,100 do x = x + 1 end 30 | if i == 10 then n = "2" end 31 | end 32 | assert(x == 1990) 33 | end 34 | 35 | do --- cannot coerce to integer at 10 36 | local function f() 37 | local n = 1 38 | local x = 0 39 | for i=1,20 do 40 | for j=n,100 do x = x + 1 end 41 | if i == 10 then n = "x" end 42 | end 43 | end 44 | assert(not pcall(f)) 45 | end 46 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/gc.lua: -------------------------------------------------------------------------------- 1 | do --- rechain 2 | local k 3 | 4 | collectgarbage() 5 | 6 | local t = {} 7 | t.ac = 1 8 | 9 | t.nn = 1 10 | t.mm = 1 11 | t.nn = nil 12 | t.mm = nil 13 | 14 | k = "a".."i" 15 | t[k] = 2 16 | 17 | t.ad = 3 18 | 19 | t[k] = nil 20 | k = nil 21 | 22 | collectgarbage() 23 | 24 | k = "a".."f" 25 | t[k] = 4 26 | 27 | t.ak = 5 28 | 29 | assert(t[k] == 4) 30 | end 31 | 32 | do --- TSETM gc 33 | local function f() 34 | collectgarbage() 35 | return "a", "b" 36 | end 37 | for i = 1, 10 do 38 | local t = {f()} 39 | assert(t[1] == "a") 40 | assert(t[2] == "b") 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/gc_stack.lua: -------------------------------------------------------------------------------- 1 | do --- Marking sparse stack. 2 | local t = setmetatable({}, { __index = function(t, k) 3 | k = k - 1 4 | if k == 0 then 5 | collectgarbage() -- Mark stack, including holes. 6 | return 0 7 | else 8 | return t[k] -- Leaves holes in each frame. 9 | end 10 | do 11 | -- Ensure bigger frame size. 12 | local a, b, c, d, e, f, g, h, i, j, k, l, m, n 13 | end 14 | end}) 15 | local x = t[50] 16 | end 17 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/gc_step.lua: -------------------------------------------------------------------------------- 1 | local function testgc(what, func) 2 | collectgarbage() 3 | local oc = gcinfo() 4 | func() 5 | local nc = gcinfo() 6 | assert(nc < oc * 4, "GC step missing for " .. what) 7 | end 8 | 9 | do --- TNEW 10 | testgc("TNEW", function() 11 | for _ = 1, 10000 do 12 | local _ = {} 13 | end 14 | end) 15 | end 16 | 17 | do --- TDUP 18 | testgc("TDUP", function() 19 | for _ = 1, 10000 do 20 | local _ = {1} 21 | end 22 | end) 23 | end 24 | 25 | do --- FNEW 26 | testgc("FNEW", function() 27 | for _ = 1, 10000 do 28 | local function _() end 29 | end 30 | end) 31 | end 32 | 33 | do --- CAT 34 | testgc("CAT", function() 35 | for i = 1, 10000 do 36 | local _ = "x" .. i 37 | end 38 | end) 39 | end 40 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/index: -------------------------------------------------------------------------------- 1 | andor.lua 2 | api_call.lua 3 | assignment.lua 4 | catch_cpp.lua -internal_unwinder 5 | catch_wrap.lua 6 | compare.lua 7 | compare_nan.lua 8 | constant 9 | deep_recursion.lua 10 | dualnum.lua 11 | for.lua 12 | hook_active.lua 13 | hook_line.lua 14 | hook_top.lua 15 | length.lua 16 | lightud.lua 17 | modulo.lua 18 | concat.lua 19 | self.lua 20 | stackov.lua 21 | stackov_c.lua 22 | table.lua 23 | parse_comp.lua 24 | parse_esc.lua 25 | parse_misc.lua 26 | upvalue 27 | tail_recursion.lua 28 | vararg_jit.lua 29 | gc.lua 30 | gc_debug.lua 31 | gc_stack.lua 32 | gc_step.lua 33 | goto.lua +goto 34 | meta 35 | wbarrier.lua 36 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/length.lua: -------------------------------------------------------------------------------- 1 | 2 | do --- length increasing and decreasing in loop 3 | local t = {} 4 | for i=1,100 do t[#t+1] = i end 5 | assert(#t == 100) 6 | for i=1,100 do t[#t] = nil end 7 | assert(#t == 0) 8 | end 9 | 10 | do --- length increasing in loop with existing element 11 | local t = {} 12 | t[90] = 999 13 | for i=1,100 do t[#t+1] = i end 14 | assert(#t > 100 and t[#t] == 100) 15 | end 16 | 17 | do --- length decreasing in loop with erased element 18 | local t = {} 19 | for i=1,100 do t[i] = i end 20 | t[10] = nil 21 | for i=1,99 do t[#t] = nil end 22 | assert(#t == 0) 23 | end 24 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/meta/eq.lua: -------------------------------------------------------------------------------- 1 | local function create(equal, v1, v2) 2 | local meta = { __eq = equal } 3 | return setmetatable({v1}, meta), setmetatable({v2}, meta) 4 | end 5 | 6 | do --- __eq xop 7 | local xop 8 | local a, b = create(function(a,b) xop = "eq" return "" end) 9 | assert(a==b == true and xop == "eq"); xop = nil 10 | assert(a~=b == false and xop == "eq"); xop = nil 11 | 12 | -- Different metatable, but same metamethod works, too. 13 | setmetatable(b, { __eq = getmetatable(b).__eq }) 14 | assert(a==b == true and xop == "eq"); xop = nil 15 | assert(a~=b == false and xop == "eq"); xop = nil 16 | end 17 | 18 | do --- __eq values 19 | local a, b = create(function(a,b) return a[1] == b[1] end, 1, 2) 20 | assert(a==b == false) 21 | assert(a~=b == true) 22 | 23 | b[1] = 1 24 | assert(a==b == true) 25 | assert(a~=b == false) 26 | 27 | a[1] = 2 28 | assert(a==b == false) 29 | assert(a~=b == true) 30 | end 31 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/meta/framegap.lua: -------------------------------------------------------------------------------- 1 | do --- untitled 2 | local t = setmetatable({}, { __add = function(a, b) 3 | if b > 200 then 4 | for j=1,10 do end 5 | return b+3 6 | elseif b > 100 then 7 | return b+2 8 | else 9 | return b+1 10 | end 11 | end }) 12 | 13 | local function f(t, i) 14 | do return t+i end 15 | -- Force large frame with unassigned slots below mm. 16 | do local a,b,c,d,e,f,g,h,i,j,k end 17 | end 18 | 19 | local x = 0 20 | for i=1,300 do 21 | x = f(t, i) 22 | end 23 | assert(x == 303) 24 | end 25 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/meta/index: -------------------------------------------------------------------------------- 1 | arith.lua 2 | arith_jit.lua 3 | call.lua 4 | cat.lua 5 | comp.lua 6 | comp_jit.lua 7 | eq.lua 8 | eq_jit.lua 9 | framegap.lua 10 | index.lua 11 | len.lua 12 | newindex.lua 13 | nomm.lua 14 | debuginfo.lua 15 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/meta/len.lua: -------------------------------------------------------------------------------- 1 | local compat52 = table.pack 2 | local mt = { __len = function(o, o2) 3 | if compat52 then 4 | assert(o2 == o) 5 | else 6 | assert(o2 == nil) 7 | end 8 | return 42 9 | end } 10 | 11 | do --- table 12 | local t = {1,2,3} 13 | assert(#t == 3) 14 | assert(#"abcdef" == 6) 15 | 16 | setmetatable(t, { __foo = function() end }) 17 | assert(#t == 3) 18 | assert(#t == 3) 19 | 20 | setmetatable(t, mt) 21 | if compat52 then 22 | assert(#t == 42) -- __len DOES work on tables. 23 | assert(rawlen(t) == 3) 24 | else 25 | assert(#t == 3) -- __len does NOT work on tables. 26 | end 27 | end 28 | 29 | do --- userdata +lua<5.2 30 | local u = newproxy(true) 31 | getmetatable(u).__len = function(o) return 42 end 32 | assert(#u == 42) 33 | local x = 0 34 | for i=1,100 do x = x + #u end 35 | assert(x == 4200) 36 | end 37 | 38 | do --- number 39 | debug.setmetatable(0, mt) 40 | assert(#1 == 42) 41 | debug.setmetatable(0, nil) 42 | end 43 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/meta/nomm.lua: -------------------------------------------------------------------------------- 1 | 2 | do --- untitled 3 | local keys = {} 4 | for i=1,100 do keys[i] = "foo" end 5 | keys[95] = "__index" 6 | local function fidx(t, k) return 12345 end 7 | local mt = { foo = 1, __index = "" } 8 | local t = setmetatable({ 1 }, mt) 9 | t[1] = nil 10 | mt.__index = nil 11 | local x = nil 12 | for i=1,100 do 13 | mt[keys[i]] = fidx 14 | if t[1] then 15 | if not x then x = i end 16 | assert(t[1] == 12345) 17 | end 18 | end 19 | assert(x == 95) 20 | end 21 | 22 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/modulo.lua: -------------------------------------------------------------------------------- 1 | local assert, floor = assert, math.floor 2 | 3 | do --- integer equivalence 4 | for x=-5,5 do 5 | for y=-5,5 do 6 | if y ~= 0 then 7 | assert(x%y == x-floor(x/y)*y) 8 | end 9 | end 10 | end 11 | end 12 | 13 | do --- fractional equivalence 14 | for x=-5,5,0.25 do 15 | for y=-5,5,0.25 do 16 | if y ~= 0 then 17 | assert(x%y == x-floor(x/y)*y) 18 | end 19 | end 20 | end 21 | end 22 | 23 | do --- jit constant RHS 24 | local y = 0 25 | for x=-100,123 do 26 | y = y + x%17 27 | end 28 | assert(y == 1777) 29 | end 30 | 31 | do --- jit constant LHS, with exit 32 | local y = 0 33 | for x=-100,123 do 34 | if x ~= 0 then 35 | y = y + 85%x 36 | end 37 | end 38 | assert(y == 2059) 39 | end 40 | 41 | do --- divide by zero 42 | local x = 1%0 43 | assert(x ~= x) 44 | x = floor(0/0) 45 | assert(x ~= x) 46 | end 47 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/parse_comp.lua: -------------------------------------------------------------------------------- 1 | do --- Parse inline comparisions expressions, base. 2 | local f = {{n = 5}} 3 | local a = f[1].n 4 | assert(1 < a) 5 | assert(1 < (f[1].n)) 6 | assert(1 < f[1].n) 7 | end 8 | 9 | do --- Parse inline comparisions expressions with not. 10 | local tt = { a = 1 } 11 | assert(not(0 >= tt.a)) 12 | end 13 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/parse_esc.lua: -------------------------------------------------------------------------------- 1 | do --- Base parsing of escape sequences. 2 | assert("\79\126" == "O~") 3 | assert("\x4f\x7e" == "O~") 4 | assert(loadstring[[return "\xxx"]] == nil) 5 | assert(loadstring[[return "\xxx"]] == nil) 6 | 7 | assert(assert(loadstring[[return "abc \z 8 | 9 | def"]])() == "abc def") 10 | end 11 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/parse_misc.lua: -------------------------------------------------------------------------------- 1 | do --- Ambiguous syntax: function call vs. new statement. +lua==5.2 2 | assert(assert(loadstring([[ 3 | local function f() return 99 end 4 | return f 5 | () 6 | ]]))() == 99) 7 | end 8 | 9 | do --- Ambiguous syntax: function call vs. new statement. +lua<5.2 10 | assert(loadstring([[ 11 | local function f() return 99 end 12 | return f 13 | () 14 | ]]) == nil) 15 | end 16 | 17 | do --- UTF-8 identifiers. 18 | assert(loadstring([[ 19 | local ä = 1 20 | local aäa = 2 21 | local äöü·€晶 = 3 22 | 23 | assert(ä == 1) 24 | assert(aäa == 2) 25 | assert(äöü·€晶 == 3) 26 | 27 | assert(#"ä" == 2) 28 | assert(#"aäa" == 4) 29 | assert(#"äöü·€晶" == 14) 30 | ]]))() 31 | end 32 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/self.lua: -------------------------------------------------------------------------------- 1 | do --- trivial setget 2 | local t = {} 3 | 4 | function t:set(x) 5 | self.a=x 6 | end 7 | 8 | function t:get() 9 | return self.a 10 | end 11 | 12 | t:set("foo") 13 | assert(t:get() == "foo") 14 | assert(t.a == "foo") 15 | 16 | t:set(42) 17 | assert(t:get() == 42) 18 | assert(t.a == 42) 19 | end 20 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/stackov_c.lua: -------------------------------------------------------------------------------- 1 | do --- Too many results to unpack. 2 | local j = 1e4 3 | local co = coroutine.create(function() 4 | local t = {} 5 | for i = 1, j do 6 | t[i] = i 7 | end 8 | return unpack(t) 9 | end) 10 | local ok, err = coroutine.resume(co) 11 | assert(not ok and string.find(err, "unpack")) 12 | end 13 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/table.lua: -------------------------------------------------------------------------------- 1 | do --- tables as keys in tables 2 | local fwd, bck = {}, {} 3 | for i = 1,100 do 4 | local v = {} 5 | fwd[i] = v 6 | bck[v] = i 7 | end 8 | for i = 1,100 do 9 | local v = fwd[i] 10 | assert(type(v) == "table") 11 | assert(bck[v] == i) 12 | end 13 | end 14 | 15 | do --- some tables as keys in tables 16 | local fwd, bck = {}, {} 17 | for i = 1,100 do 18 | local v = {} 19 | fwd[i] = v 20 | if i > 90 then 21 | bck[v] = i 22 | end 23 | end 24 | local n = 0 25 | for i = 1, 100 do 26 | local v = fwd[i] 27 | if bck[v] then 28 | n = n + 1 29 | end 30 | end 31 | assert(n == 10) 32 | end 33 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/tail_recursion.lua: -------------------------------------------------------------------------------- 1 | do --- self 2 | local tr1 3 | function tr1(n) 4 | if n <= 0 then return 0 end 5 | return tr1(n-1) 6 | end 7 | assert(tr1(200) == 0) 8 | end 9 | 10 | do --- mutual 11 | local tr1, tr2 12 | function tr1(n) 13 | if n <= 0 then return 0 end 14 | return tr2(n-1) 15 | end 16 | function tr2(n) 17 | return tr1(n) 18 | end 19 | assert(tr2(200) == 0) 20 | end 21 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/upvalue/index: -------------------------------------------------------------------------------- 1 | closure.lua 2 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lang/wbarrier.lua: -------------------------------------------------------------------------------- 1 | do --- Check write barrier when insert strings. 2 | local t = {} 3 | 4 | for i = 1, 20000 do 5 | t[i] = tostring(i) 6 | end 7 | 8 | for i = 1, #t do 9 | assert(t[i] == tostring(i)) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/base/assert.lua: -------------------------------------------------------------------------------- 1 | do --- pass through one 2 | assert(assert(true) == true) 3 | assert(assert(3) == 3) 4 | assert(assert(1.5) == 1.5) 5 | assert(assert("x") == "x") 6 | local f = function() end 7 | assert(assert(f) == f) 8 | local t = {} 9 | assert(assert(t) == t) 10 | end 11 | 12 | do --- pass through many 13 | local b, c = assert("b", "c") 14 | assert(b == "b") 15 | assert(c == "c") 16 | local d, e, f, g = assert("d", 5, true, false) 17 | assert(d == "d") 18 | assert(e == 5) 19 | assert(f == true) 20 | assert(g == false) 21 | end 22 | 23 | do --- raise on nil 24 | local ok, err = pcall(assert, nil) 25 | assert(ok == false) 26 | assert(err == "assertion failed!") 27 | end 28 | 29 | do --- raise on false 30 | local ok, err = pcall(assert, false, "msg") 31 | assert(ok == false) 32 | assert(err == "msg") 33 | end 34 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/base/error.lua: -------------------------------------------------------------------------------- 1 | do --- no message 2 | local ok, msg = pcall(error) 3 | assert(ok == false) 4 | assert(msg == nil) 5 | end 6 | 7 | do --- level 0 8 | local ok, msg = pcall(error, "emsg", 0) 9 | assert(ok == false) 10 | assert(msg == "emsg") 11 | end 12 | 13 | do --- default level 14 | local ok, msg = pcall(error, "emsg") 15 | assert(ok == false) 16 | assert(msg == "emsg") 17 | end 18 | 19 | do --- default level in xpcall 20 | local line 21 | local ok, msg = xpcall(function() 22 | local x 23 | line = debug.getinfo(1, "l").currentline; error("emsg") 24 | end, function(m) 25 | assert(debug.getlocal(3, 1) == "x") 26 | return m .."xp" 27 | end) 28 | assert(ok == false) 29 | assert(msg:find("^.-:".. line ..": emsgxp$")) 30 | end 31 | 32 | do --- level 2 in xpcall 33 | local line 34 | local ok, msg = xpcall(function() 35 | local function f() error("emsg", 2) end 36 | line = debug.getinfo(1, "l").currentline; f() 37 | end, function(m) 38 | assert(debug.getlocal(4, 1) == "f") 39 | return m .."xp2" 40 | end) 41 | assert(ok == false) 42 | assert(msg:find("^.-:".. line ..": emsgxp2$")) 43 | end 44 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/base/getfenv.lua: -------------------------------------------------------------------------------- 1 | do --- untitled 2 | local x 3 | local function f() 4 | x = getfenv(0) 5 | end 6 | local co = coroutine.create(f) 7 | local t = {} 8 | debug.setfenv(co, t) 9 | for i=1,50 do f() f() f() end 10 | assert(x == getfenv(0)) 11 | coroutine.resume(co) 12 | assert(x == t) 13 | end 14 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/base/getsetmetatable.lua: -------------------------------------------------------------------------------- 1 | 2 | do --- get __metatable 3 | local t = setmetatable({}, { __metatable = "foo" }) 4 | for i=1,100 do assert(getmetatable(t) == "foo") end 5 | end 6 | 7 | do --- jit smoke 8 | local mt = {} 9 | local t = setmetatable({}, mt) 10 | for i=1,100 do assert(getmetatable(t) == mt) end 11 | for i=1,100 do assert(setmetatable(t, mt) == t) end 12 | end 13 | 14 | do --- jit assorted 15 | local mt = {} 16 | local t = {} 17 | for i=1,200 do t[i] = setmetatable({}, mt) end 18 | t[150] = setmetatable({}, { __metatable = "foo" }) 19 | for i=1,200 do 20 | if not pcall(setmetatable, t[i], mt) then assert(i == 150) end 21 | end 22 | for i=1,200 do assert(getmetatable(t[i]) == mt or i == 150) end 23 | for i=1,200 do 24 | if not pcall(setmetatable, t[i], nil) then assert(i == 150) end 25 | end 26 | for i=1,200 do assert(getmetatable(t[i]) == nil or i == 150) end 27 | end 28 | 29 | do --- jit get primitive metatable 30 | local x = true 31 | for i=1,100 do x = getmetatable(i) end 32 | assert(x == nil) 33 | end 34 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/base/index: -------------------------------------------------------------------------------- 1 | assert.lua 2 | error.lua 3 | getfenv.lua +lua<5.2 4 | getsetmetatable.lua 5 | ipairs.lua 6 | next.lua 7 | pairs.lua 8 | pcall_jit.lua 9 | select.lua 10 | tonumber_tostring.lua 11 | tonumber_scan.lua +ffi 12 | xpcall_jit.lua +compat5.2 13 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/base/ipairs.lua: -------------------------------------------------------------------------------- 1 | do --- small integer values 2 | local t = { 4,5,6,7,8,9,10 } 3 | local n = 0 4 | for i,v in ipairs(t) do 5 | assert(v == i+3) 6 | n = n + 1 7 | end 8 | assert(n == 7) 9 | end 10 | 11 | do --- jit key=value 12 | local t = {} 13 | for i=1,100 do t[i]=i end 14 | local n = 0 15 | for i,v in ipairs(t) do 16 | assert(i == v) 17 | n = n + 1 18 | end 19 | assert(n == 100) 20 | end 21 | 22 | do --- untitled 23 | local t = {} 24 | local o = {{}, {}} 25 | for i=1,100 do 26 | local c = i.."" 27 | t[i] = c 28 | o[1][c] = i 29 | o[2][c] = i 30 | end 31 | o[1]["90"] = nil 32 | 33 | local n = 0 34 | for _, c in ipairs(t) do 35 | for i = 1, 2 do 36 | o[i][c] = o[i][c] or 1 37 | n = n + 1 38 | end 39 | end 40 | assert(n == 200) 41 | end 42 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/base/next.lua: -------------------------------------------------------------------------------- 1 | do --- _G 1 2 | local ok, err = pcall(next, _G, 1) 3 | assert(not ok) 4 | local ok, err = pcall(function() next(_G, 1) end) 5 | assert(not ok) 6 | end 7 | 8 | do --- as iterator 9 | local t = { foo = 9, bar = 10, 4, 5, 6 } 10 | local r = {} 11 | local function dummy() end 12 | local function f(next) 13 | for k,v in next,t,nil do r[#r+1] = k; if v == 5 then f(dummy) end end 14 | end 15 | f(next) 16 | assert(#r == 5) 17 | end 18 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/coroutine/index: -------------------------------------------------------------------------------- 1 | traceback.lua 2 | yield.lua 3 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/coroutine/traceback.lua: -------------------------------------------------------------------------------- 1 | do --- traceback 2 | local function badfunc() 3 | local x = nil 4 | local y = x.x 5 | end 6 | 7 | local co = coroutine.create(badfunc) 8 | assert(coroutine.resume(co) == false) 9 | 10 | local traceback = debug.traceback(co) 11 | local line = debug.getinfo(badfunc).linedefined 12 | 13 | assert(traceback:match('traceback:.*:' .. line)) 14 | end 15 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/ffi/index: -------------------------------------------------------------------------------- 1 | bit64.lua +luajit>=2.1 2 | cdata_var.lua 3 | copy_fill.lua 4 | err.lua 5 | ffi_arith_ptr.lua 6 | ffi_bitfield.lua 7 | ffi_call.lua 8 | ffi_callback.lua 9 | ffi_const.lua 10 | ffi_convert.lua 11 | ffi_enum.lua 12 | ffi_gcstep_recursive.lua 13 | ffi_jit_arith.lua 14 | ffi_jit_call.lua 15 | ffi_jit_conv.lua 16 | ffi_lex_number.lua 17 | ffi_metatype.lua 18 | ffi_new.lua 19 | ffi_parse_array.lua 20 | ffi_parse_basic.lua 21 | ffi_parse_cdef.lua 22 | ffi_parse_struct.lua 23 | istype.lua 24 | jit_array.lua 25 | jit_complex.lua 26 | jit_misc.lua 27 | jit_struct.lua 28 | meta_tostring.lua 29 | redir.lua 30 | type_punning.lua 31 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/ffi/redir.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | do --- function 4 | ffi.cdef[[ 5 | int redir_foo(const char *s) asm("strlen"); 6 | ]] 7 | 8 | assert(ffi.C.redir_foo("abcd") == 4) 9 | end 10 | 11 | do --- variable -windows 12 | ffi.cdef[[ 13 | int redir_bar asm("errno"); 14 | ]] 15 | 16 | ffi.C.redir_bar = 14 17 | assert(ffi.C.redir_bar == 14) 18 | ffi.C.redir_bar = 0 19 | end 20 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/index: -------------------------------------------------------------------------------- 1 | base 2 | bit.lua +bit 3 | math 4 | string 5 | table 6 | coroutine 7 | ffi +ffi 8 | contents.lua -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/math/abs.lua: -------------------------------------------------------------------------------- 1 | local abs = math.abs 2 | local expect_error = require"common.expect_error" 3 | 4 | do --- smoke 5 | assert(abs(-1.5) == 1.5) 6 | assert(abs("-1.5") == 1.5) 7 | end 8 | 9 | do --- argcheck 10 | expect_error(function() abs() end, 11 | "bad argument #1 to 'abs' (number expected, got no value)") 12 | expect_error(function() abs(false) end, 13 | "bad argument #1 to 'abs' (number expected, got boolean)") 14 | expect_error(function() abs("a") end, 15 | "bad argument #1 to 'abs' (number expected, got string)") 16 | end 17 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/math/constants.lua: -------------------------------------------------------------------------------- 1 | do --- pi 2 | assert(math.pi == 3.141592653589793) 3 | end 4 | 5 | do --- huge 6 | assert(math.huge > 0) 7 | assert(1/math.huge == 0) 8 | end 9 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/math/index: -------------------------------------------------------------------------------- 1 | abs.lua 2 | constants.lua 3 | random.lua 4 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/string/char.lua: -------------------------------------------------------------------------------- 1 | local char = string.char 2 | 3 | do --- jit one char 4 | local y 5 | for i=1,100 do y = char(65) end 6 | assert(y == "A") 7 | local x = 97 8 | for i=1,100 do y = char(x) end 9 | assert(y == "a") 10 | x = "98" 11 | for i=1,100 do y = char(x) end 12 | assert(y == "b") 13 | for i=1,100 do y = char(32+i) end 14 | assert(y == "\132") 15 | end 16 | 17 | do --- jit until out of bounds 18 | local y 19 | assert(not pcall(function() 20 | for i=1,200 do y = char(100+i) end 21 | end)) 22 | assert(y == "\255") 23 | end 24 | 25 | do --- jit five chars 26 | local y 27 | for i=1,100 do y = char(65, 66, i, 67, 68) end 28 | assert(y == "ABdCD") 29 | end 30 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/string/dump.lua: -------------------------------------------------------------------------------- 1 | local loadstring = loadstring or load 2 | 3 | do --- Must unpatch modified bytecode with ILOOP/JLOOP etc. -table_bump 4 | local function foo() 5 | local t = {} 6 | for i=1,100 do t[i] = i end 7 | for a,b in ipairs(t) do end 8 | local m = 0 9 | while m < 100 do m = m + 1 end 10 | end 11 | 12 | local d1 = string.dump(foo) 13 | foo() 14 | assert(string.dump(foo) == d1) 15 | if jit then jit.off(foo) end 16 | foo() 17 | assert(string.dump(foo) == d1) 18 | local d2 = string.dump(loadstring(d1, ""), true) 19 | local d3 = string.dump(assert(loadstring(d2, "")), true) 20 | assert(d2 == d3) 21 | assert(loadstring(string.dump(assert(loadstring(d2, ""))))) 22 | end 23 | 24 | do --- roundtrip constants 25 | local function f1() return -0x80000000 end 26 | local function f2() return 0.971234567 end 27 | assert(f1() == -0x80000000) 28 | assert(loadstring(string.dump(f1), "")() == -0x80000000) 29 | assert(f2() == 0.971234567) 30 | assert(loadstring(string.dump(f2), "")() == 0.971234567) 31 | end 32 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/string/format/index: -------------------------------------------------------------------------------- 1 | num.lua 2 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/string/index: -------------------------------------------------------------------------------- 1 | metatable.lua 2 | byte.lua 3 | char.lua 4 | dump.lua 5 | format 6 | len.lua 7 | lower_upper.lua 8 | multiple_functions.lua 9 | rep.lua 10 | reverse.lua 11 | sub.lua 12 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/string/len.lua: -------------------------------------------------------------------------------- 1 | local len = string.len 2 | local expect_error = require"common.expect_error" 3 | 4 | do --- smoke 5 | assert(len("abc") == 3) 6 | assert(len(123) == 3) 7 | end 8 | 9 | do --- argcheck 10 | expect_error(function() len() end, 11 | "bad argument #1 to 'len' (string expected, got nil)") 12 | expect_error(function() len(false) end, 13 | "bad argument #1 to 'len' (string expected, got boolean)") 14 | end 15 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/string/metatable.lua: -------------------------------------------------------------------------------- 1 | do --- __index metamethod is string library 2 | assert(debug.getmetatable("").__index == string) 3 | end 4 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/string/multiple_functions.lua: -------------------------------------------------------------------------------- 1 | do --- string_op 2 | local t, y = {}, {} 3 | for i=1,100 do t[i] = string.char(i, 16+i, 32+i) end 4 | for i=1,100 do t[i] = string.reverse(t[i]) end 5 | assert(t[100] == "\132\116\100") 6 | for i=1,100 do t[i] = string.reverse(t[i]) end 7 | for i=1,100 do assert(t[i] == string.char(i, 16+i, 32+i)) end 8 | for i=1,100 do y[i] = string.upper(t[i]) end 9 | assert(y[65] == "AQA") 10 | assert(y[97] == "AQ\129") 11 | assert(y[100] == "DT\132") 12 | for i=1,100 do y[i] = string.lower(t[i]) end 13 | assert(y[65] == "aqa") 14 | assert(y[97] == "aq\129") 15 | assert(y[100] == "dt\132") 16 | end 17 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/string/reverse.lua: -------------------------------------------------------------------------------- 1 | local reverse = string.reverse 2 | 3 | do --- misc 4 | local y 5 | for i=1,100 do y = reverse("abc") end 6 | assert(y == "cba") 7 | local x = "abcd" 8 | for i=1,100 do y = reverse(x) end 9 | assert(y == "dcba") 10 | x = 1234 11 | for i=1,100 do y = reverse(x) end 12 | assert(y == "4321") 13 | end 14 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/table/index: -------------------------------------------------------------------------------- 1 | concat.lua 2 | insert.lua 3 | new.lua +table.new 4 | pack.lua +compat5.2 5 | remove.lua 6 | sort.lua 7 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/table/insert.lua: -------------------------------------------------------------------------------- 1 | local tinsert = table.insert 2 | local assert = assert 3 | 4 | do --- table.insert(t,i) 5 | local t = {} 6 | for i=1,100 do t[i] = i end 7 | for i=1,100 do tinsert(t, i) end 8 | assert(#t == 200 and t[100] == 100 and t[200] == 100) 9 | end 10 | 11 | do --- table.insert(t,i,i) 12 | local t = {} 13 | for i=1,200 do t[i] = i end 14 | for i=101,200 do tinsert(t, i, i) end 15 | assert(#t == 300 and t[101] == 101 and t[200] == 200 and t[300] == 200) 16 | end 17 | 18 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/table/new.lua: -------------------------------------------------------------------------------- 1 | local tnew = require"table.new" 2 | 3 | do --- table.new 4 | local x, y 5 | for i=1,100 do 6 | x = tnew(100, 30) 7 | assert(type(x) == "table") 8 | if i == 90 then y = x end 9 | end 10 | assert(x ~= y) 11 | end 12 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/table/pack.lua: -------------------------------------------------------------------------------- 1 | do --- empty 2 | local t = table.pack() 3 | assert(type(t) == "table") 4 | assert(t.n == 0) 5 | assert(t[0] == nil) 6 | assert(t[1] == nil) 7 | end 8 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/lib/table/sort.lua: -------------------------------------------------------------------------------- 1 | -- Really a test for lua_lessthan() 2 | local N = 1000 3 | 4 | do --- numbers 5 | math.randomseed(42) 6 | local t = {} 7 | for i=1,N do t[i] = math.random(N) end 8 | table.sort(t) 9 | for i=2,N do assert(t[i-1] <= t[i]) end 10 | end 11 | 12 | do --- strings 13 | math.randomseed(42) 14 | local t = {} 15 | for i=1,N do t[i] = math.random(1, N/10).."" end 16 | table.sort(t) 17 | for i=2,N do assert(t[i-1] <= t[i]) end 18 | end 19 | 20 | do --- tables 21 | math.randomseed(42) 22 | local mt = { __lt = function(a,b) return a[1] < b[1] end } 23 | local t = {} 24 | for i=1,N do t[i] = setmetatable({ math.random(N) }, mt) end 25 | table.sort(t) 26 | for i=2,N do assert(t[i-1][1] <= t[i][1]) end 27 | end 28 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/opt/dse/index: -------------------------------------------------------------------------------- 1 | array.lua 2 | field.lua 3 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/opt/fold/index: -------------------------------------------------------------------------------- 1 | kfold.lua 2 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/opt/fuse.lua: -------------------------------------------------------------------------------- 1 | do --- Don't fuse i+101 on x64. 2 | -- (except if i is sign-extended to 64 bit or addressing is limited to 32 bit) 3 | local t = {} 4 | for i=-100,-1 do t[i+101] = 1 end 5 | end 6 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/opt/fwd/hrefk_rollback.lua: -------------------------------------------------------------------------------- 1 | do --- https://github.com/LuaJIT/LuaJIT/issues/124 2 | local function foo(a, b, f) 3 | return f and (a.f0 < b.f1 and 4 | b.f0 < a.f1 and 5 | a.f2 < b.f3 and 6 | b.f2 < a.f3) 7 | end 8 | 9 | local function bar(f0, f1, f2, f3, X, f) 10 | for _, v in ipairs(X) do 11 | local b = {} 12 | b.f0 = 0 13 | b.f2 = v 14 | b.f1 = b.f0 + 1 15 | b.f3 = b.f2 + 1 16 | 17 | if foo({f0 = f0, f1 = f1, f2 = f2, f3 = f3}, b, f) then 18 | return false 19 | end 20 | end 21 | 22 | return true 23 | end 24 | 25 | local X = { 0, 1, 0, 0 } 26 | 27 | for i = 1, 20 do 28 | assert(bar(0, 1, 2, 3, X, true)) 29 | end 30 | 31 | assert(not bar(0, 1, 1, 2, X, true)) 32 | end 33 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/opt/fwd/index: -------------------------------------------------------------------------------- 1 | hrefk_rollback.lua 2 | tnew_tdup.lua 3 | upval.lua 4 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/opt/index: -------------------------------------------------------------------------------- 1 | dse +dse 2 | fold +fold 3 | fwd +fwd 4 | fuse.lua +fuse 5 | loop +loop 6 | mem +cse +dse +fold +fwd 7 | sink +sink 8 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/opt/loop/index: -------------------------------------------------------------------------------- 1 | unroll.lua 2 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/opt/loop/unroll.lua: -------------------------------------------------------------------------------- 1 | do --- type instability on loop unroll -> record unroll 2 | local flip = true 3 | for i=1,100 do flip = not flip end 4 | assert(flip == true) 5 | end 6 | 7 | do --- untitled 8 | local t = {} 9 | local a, b, c = 1, "", t 10 | for i=1,100 do a,b,c=b,c,a end 11 | assert(c == 1 and a == "" and b == t) 12 | end 13 | 14 | do --- FAILFOLD on loop unroll -> LJ_TRERR_GFAIL -> record unroll 15 | local t = { 1, 2 } 16 | local k = 2 17 | local x = 0 18 | for i=1,200 do 19 | x = x + t[k] 20 | k = k == 1 and 2 or 1 21 | end 22 | assert(x == 300 and k == 2) 23 | end 24 | 25 | do --- Unroll if inner loop aborts. 26 | local j = 0 27 | for i = 1,100 do 28 | repeat 29 | j = j+1 30 | until true 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/opt/mem/index: -------------------------------------------------------------------------------- 1 | alias_alloc.lua 2 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/opt/sink/ffi_nosink.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | do --- escaping global !private_G 4 | local x = 0ll 5 | for i=1,100 do x=x+1; g=x end 6 | assert(x == 100ll) 7 | assert(g == 100ll) 8 | end 9 | 10 | do --- preincrement escaping global !private_G 11 | local x = 0ll 12 | for i=1,100 do local y=x; x=x+1; g=y end 13 | assert(x == 100ll) 14 | assert(g == 99ll) 15 | end 16 | 17 | do --- escaping global and local !private_G 18 | local x = 0ll 19 | local z 20 | for i=1,100 do z=x+1; g=z end 21 | assert(z == 1ll) 22 | assert(g == 1ll) 23 | end 24 | 25 | do --- swapping 26 | local x,y = 0ll, 0ll 27 | for i=1,100 do y,x=x,x+1 end 28 | assert(x == 100ll) 29 | assert(y == 99ll) 30 | end 31 | 32 | do --- pointer to self 33 | local st = ffi.typeof("struct { void *p; }") 34 | local x 35 | for i=1,100 do x = st(); x.p = x end 36 | assert(x.p == ffi.cast("void *", x)) 37 | end 38 | 39 | do --- strchr 40 | ffi.cdef[[char *strchr(char *, int);]] 41 | for i=1,100 do 42 | local p = ffi.new("char[2]"); 43 | ffi.C.strchr(p, 32) 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/opt/sink/index: -------------------------------------------------------------------------------- 1 | alloc.lua 2 | nosink.lua 3 | ffi.lua +ffi 4 | ffi_nosink.lua +ffi 5 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Use `lib` prefix for loading via FFI and `require()`. 2 | AddTestLib(libctest libctest.c) 3 | enable_language(CXX) 4 | AddTestLib(libcpptest libcpptest.cpp) 5 | 6 | add_custom_target(LuaJIT-tests-libs DEPENDS ${TESTLIBS}) 7 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/sysdep/ffi_include_gtk.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | dofile("../common/ffi_util.inc") 4 | 5 | if cdefs == "" then 6 | cdefs = "-pthread -D_REENTRANT -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/directfb -I/usr/include/libpng12 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/gdk-pixbuf-2.0" 7 | end 8 | 9 | include"/usr/include/gtk-2.0/gtk/gtk.h" 10 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/sysdep/ffi_include_std.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | dofile("../common/ffi_util.inc") 4 | 5 | do 6 | local fp = assert(io.open("/tmp/__tmp.c", "w")) 7 | fp:write[[ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | ]] 27 | fp:close() 28 | 29 | local flags = ffi.abi("32bit") and "-m32" or "-m64" 30 | fp = assert(io.popen("cc -E -P -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE /tmp/__tmp.c "..flags)) 31 | local s = fp:read("*a") 32 | fp:close() 33 | os.remove("/tmp/__tmp.c") 34 | ffi.cdef(s) 35 | end 36 | 37 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/trace/exit_growstack.lua: -------------------------------------------------------------------------------- 1 | do --- Exit needs to grow stack before slot fill. 2 | local function f(i) 3 | local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; 4 | local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; 5 | local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; 6 | if i==90 then return end 7 | end 8 | for j=1,5 do 9 | collectgarbage() -- Shrink stack. 10 | for i=1,100 do f(i) end 11 | end 12 | end 13 | 14 | do --- Exit needs to grow stack after slot fill. 15 | local function g(i) 16 | if i==90 then return end 17 | do return end 18 | do 19 | local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; 20 | local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; 21 | local a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a; 22 | end 23 | end 24 | for j=1,5 do 25 | collectgarbage() -- Shrink stack. 26 | for i=1,100 do g(i) end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/trace/gc.lua: -------------------------------------------------------------------------------- 1 | local jutil = require("jit.util") 2 | 3 | do --- Collect dead traces. 4 | jit.flush() 5 | collectgarbage() 6 | -- Prevent the creation of side traces. 7 | jit.off() 8 | for _ = 1, 100 do 9 | jit.on() 10 | loadstring("for _ = 1, 100 do end")() 11 | jit.off() 12 | end 13 | jit.on() 14 | collectgarbage() 15 | assert(jutil.traceinfo(1) == nil) 16 | assert(jutil.traceinfo(2) == nil) 17 | assert(jutil.traceinfo(3) == nil) 18 | end 19 | 20 | do --- Check KGC marking. 21 | local f 22 | local function reccb(tr) 23 | if f == nil then 24 | collectgarbage() 25 | local info = jutil.traceinfo(tr) 26 | jutil.tracek(tr, -info.nk) 27 | -- Error in lj_ir_kvalue() if KGC not marked. 28 | -- Only caught with assertions or Valgrind. 29 | end 30 | end 31 | jit.attach(reccb, "record") 32 | for i = 1, 200 do 33 | if i % 5 == 0 then 34 | f = function() end 35 | elseif f then 36 | f() 37 | f = nil 38 | end 39 | end 40 | jit.attach(reccb) 41 | end 42 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/trace/gc64_slot_revival.lua: -------------------------------------------------------------------------------- 1 | do --- BC_KNIL 2 | local function f(x, y) end 3 | for i = 1,100 do 4 | f(i, i) 5 | f(nil, nil) 6 | end 7 | end 8 | 9 | do --- BC_VARG 10 | local function f() end 11 | local function g(...) 12 | f() 13 | f(...) 14 | end 15 | for i = 1,100 do 16 | g() 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/trace/hook_norecord.lua: -------------------------------------------------------------------------------- 1 | do --- Abort trace recording on any hook call. 2 | local called = false 3 | local function f() local x = "wrong"; called = true end 4 | jit.off(f) 5 | jit.flush() 6 | debug.sethook(f, "", 5) 7 | for _ = 1, 1000 do local a, b, c, d, e, f = 1, 2, 3, 4, 5, 6 end 8 | assert(called) 9 | -- Check that no trace was generated. 10 | assert(require("jit.util").traceinfo(1) == nil) 11 | debug.sethook() 12 | end 13 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/trace/hook_record.lua: -------------------------------------------------------------------------------- 1 | do --- Recording traces inside the hook. 2 | jit.flush() 3 | debug.sethook(function() for _ = 1, 1000 do end end, "", 10) 4 | for _ = 1, 10 do end 5 | debug.sethook() 6 | assert((require("jit.util").traceinfo(1))) 7 | end 8 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/trace/index: -------------------------------------------------------------------------------- 1 | exit_frame.lua 2 | exit_growstack.lua 3 | exit_jfuncf.lua 4 | gc.lua 5 | gc64_slot_revival.lua 6 | hook_norecord.lua 7 | hook_record.lua 8 | jit_flush.lua 9 | phi 10 | snap.lua 11 | stack_purge.lua 12 | stitch.lua 13 | tcall_base.lua 14 | tcall_loop.lua 15 | unordered_jit.lua 16 | wbarrier.lua 17 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/trace/phi/index: -------------------------------------------------------------------------------- 1 | copyspill.lua 2 | conv.lua 3 | ref.lua 4 | rotate.lua 5 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/trace/stack_purge.lua: -------------------------------------------------------------------------------- 1 | -- Must preserve the modified function slot in the RET snapshot. 2 | local function a() 3 | local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ 4 | local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ 5 | local _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ 6 | return 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 7 | end 8 | 9 | local function b() 10 | return a() 11 | end 12 | 13 | local function c() 14 | for _ = 1, 10 do 15 | for _ = 1, 50 do b() b() b() end 16 | collectgarbage() 17 | local t = {} 18 | for _ = 1, 50 do t = {t} end 19 | end 20 | end 21 | 22 | do --- Don't purge the function to return from SNAP. 23 | jit.off(c) 24 | c() 25 | end 26 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/trace/stitch.lua: -------------------------------------------------------------------------------- 1 | do --- octal 2 | local tonumber = tonumber 3 | local function octal(s) return tonumber(s, 8) end 4 | for i=1,100 do 5 | octal("1") 6 | octal("1") 7 | octal("1") 8 | end 9 | end 10 | 11 | do --- coroutines 12 | local t = { 13 | [0] = function() end, 14 | coroutine.wrap(function() while true do coroutine.yield() end end), 15 | } 16 | for i=1,100 do 17 | t[i % 2]() 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/trace/tcall_base.lua: -------------------------------------------------------------------------------- 1 | local r = 0 2 | local function g() 3 | r = r + 1 4 | for _ = 1, 100 do end 5 | end 6 | 7 | local function f() 8 | for j = 1, 20 do 9 | if j > 19 then 10 | return g() -- Tailcall at base. 11 | -- Let this link to the already compiled loop in g(). 12 | end 13 | end 14 | end 15 | 16 | do --- Recording tailcall at base slot. 17 | g() -- Compile this loop first. 18 | for _ = 1, 50 do f() end 19 | assert(r == 51) 20 | end 21 | -------------------------------------------------------------------------------- /test/LuaJIT-tests/trace/tcall_loop.lua: -------------------------------------------------------------------------------- 1 | local function f(i) 2 | if i > 0 then return f(i - 1) end 3 | return 1 4 | end 5 | 6 | do --- Recording tailcall with the loop for the tail recursion. 7 | local x = 0 8 | for _ = 1, 100 do x = x + f(1000) end 9 | assert(x == 100) 10 | end 11 | -------------------------------------------------------------------------------- /test/PUC-Rio-Lua-5.1-tests/db.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tarantool/luajit/24d66ccea14b1292422a103b38dbc8c971e05937/test/PUC-Rio-Lua-5.1-tests/db.lua -------------------------------------------------------------------------------- /test/PUC-Rio-Lua-5.1-tests/files.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tarantool/luajit/24d66ccea14b1292422a103b38dbc8c971e05937/test/PUC-Rio-Lua-5.1-tests/files.lua -------------------------------------------------------------------------------- /test/PUC-Rio-Lua-5.1-tests/libs/lib1.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** compile with 3 | ** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c 4 | ** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3 5 | ** gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c 6 | */ 7 | 8 | 9 | #include "lua.h" 10 | #include "lauxlib.h" 11 | 12 | static int id (lua_State *L) { 13 | return lua_gettop(L); 14 | } 15 | 16 | 17 | static const struct luaL_Reg funcs[] = { 18 | {"id", id}, 19 | {NULL, NULL} 20 | }; 21 | 22 | 23 | int anotherfunc (lua_State *L) { 24 | lua_pushfstring(L, "%f%f\n", lua_tonumber(L, 1), lua_tonumber(L, 2)); 25 | return 1; 26 | } 27 | 28 | 29 | int luaopen_lib1_sub (lua_State *L) { 30 | luaL_register(L, "lib1.sub", funcs + 1); 31 | return 1; 32 | } 33 | 34 | 35 | int luaopen_lib1 (lua_State *L) { 36 | luaL_register(L, "lib1", funcs); 37 | return 1; 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /test/PUC-Rio-Lua-5.1-tests/libs/lib11.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** compile with 3 | ** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c 4 | ** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3 5 | ** gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c 6 | */ 7 | 8 | 9 | #include "lua.h" 10 | 11 | 12 | int luaopen_lib1 (lua_State *L); 13 | 14 | int luaopen_lib11 (lua_State *L) { 15 | return luaopen_lib1(L); 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/PUC-Rio-Lua-5.1-tests/libs/lib2.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** compile with 3 | ** gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c 4 | */ 5 | 6 | 7 | #include "lua.h" 8 | #include "lauxlib.h" 9 | 10 | static int id (lua_State *L) { 11 | return lua_gettop(L); 12 | } 13 | 14 | 15 | static const struct luaL_Reg funcs[] = { 16 | {"id", id}, 17 | {NULL, NULL} 18 | }; 19 | 20 | 21 | int luaopen_lib2 (lua_State *L) { 22 | luaL_register(L, "lib2", funcs); 23 | lua_pushnumber(L, 0.5); 24 | lua_setglobal(L, "x"); 25 | return 1; 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /test/PUC-Rio-Lua-5.1-tests/libs/lib21.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** compile with 3 | ** Linux: gcc -Wall -O2 -I.. -ansi -shared -o lib1.so lib1.c 4 | ** Mac OS X: export MACOSX_DEPLOYMENT_TARGET=10.3 5 | ** gcc -bundle -undefined dynamic_lookup -Wall -O2 -o lib1.so lib1.c 6 | */ 7 | 8 | 9 | #include "lua.h" 10 | 11 | 12 | int luaopen_lib2 (lua_State *L); 13 | 14 | int luaopen_lib21 (lua_State *L) { 15 | return luaopen_lib2(L); 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/PUC-Rio-Lua-5.1-tests/literals.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tarantool/luajit/24d66ccea14b1292422a103b38dbc8c971e05937/test/PUC-Rio-Lua-5.1-tests/literals.lua -------------------------------------------------------------------------------- /test/PUC-Rio-Lua-5.1-tests/pm.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tarantool/luajit/24d66ccea14b1292422a103b38dbc8c971e05937/test/PUC-Rio-Lua-5.1-tests/pm.lua -------------------------------------------------------------------------------- /test/PUC-Rio-Lua-5.1-tests/sort.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tarantool/luajit/24d66ccea14b1292422a103b38dbc8c971e05937/test/PUC-Rio-Lua-5.1-tests/sort.lua -------------------------------------------------------------------------------- /test/PUC-Rio-Lua-5.1-tests/strings.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tarantool/luajit/24d66ccea14b1292422a103b38dbc8c971e05937/test/PUC-Rio-Lua-5.1-tests/strings.lua -------------------------------------------------------------------------------- /test/cmake/GetLinuxDistro.cmake: -------------------------------------------------------------------------------- 1 | # Determine the Linux distro id and return it in the `output` 2 | # variable. See https://www.linux.org/docs/man5/os-release.html 3 | # for details. 4 | macro(GetLinuxDistro output) 5 | if(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") 6 | message(FATAL_ERROR "GetLinuxDistro macro must be used only on Linux") 7 | endif() 8 | set(OS_RELEASE_FILE /etc/os-release) 9 | if(NOT EXISTS ${OS_RELEASE_FILE}) 10 | set(OS_RELEASE_FILE /usr/lib/os-release) 11 | endif() 12 | file(READ ${OS_RELEASE_FILE} OS_RELEASE) 13 | string(REGEX MATCH "ID=([0-9a-z._-]+)" MATCH ${OS_RELEASE}) 14 | if(MATCH) 15 | set(${output} ${CMAKE_MATCH_1}) 16 | else() 17 | set(${output} linux) 18 | endif() 19 | unset(OS_RELEASE_FILE) 20 | unset(OS_RELEASE) 21 | unset(MATCH) 22 | unset(CMAKE_MATCH_1) 23 | endmacro() 24 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/000-sanity.t: -------------------------------------------------------------------------------- 1 | #! /usr/bin/lua 2 | -- 3 | -- lua-Harness : 4 | -- 5 | -- Copyright (C) 2009-2018, Perrad Francois 6 | -- 7 | -- This code is licensed under the terms of the MIT/X11 license, 8 | -- like Lua itself. 9 | -- 10 | 11 | --[[ 12 | 13 | =head1 Lua test suite 14 | 15 | =head2 Synopsis 16 | 17 | % prove 000-sanity.t 18 | 19 | =head2 Description 20 | 21 | =cut 22 | 23 | ]] 24 | 25 | function f (n) 26 | return n + 1 27 | end 28 | 29 | function g (m, p) 30 | return m + p 31 | end 32 | 33 | print('1..9') 34 | print("ok 1 -") 35 | print('ok', 2, "- list") 36 | print("ok " .. tostring(3) .. " - concatenation") 37 | i = 4 38 | print("ok " .. tostring(i) .. " - var") 39 | i = i + 1 40 | print("ok " .. tostring(i) .. " - var incr") 41 | print("ok " .. tostring(i+1) .. " - expr") 42 | j = f(i + 1) 43 | print("ok " .. tostring(j) .. " - call f") 44 | k = g(i, 3) 45 | print("ok " .. tostring(k) .. " - call g") 46 | local print = print 47 | print("ok 9 - local") 48 | 49 | -- Local Variables: 50 | -- mode: lua 51 | -- lua-indent-level: 4 52 | -- fill-column: 100 53 | -- End: 54 | -- vim: ft=lua expandtab shiftwidth=4: 55 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/090-tap.t: -------------------------------------------------------------------------------- 1 | #! /usr/bin/lua 2 | -- 3 | -- lua-Harness : 4 | -- 5 | -- Copyright (C) 2018-2021, Perrad Francois 6 | -- 7 | -- This code is licensed under the terms of the MIT/X11 license, 8 | -- like Lua itself. 9 | -- 10 | 11 | --[[ 12 | 13 | =head1 Lua test suite 14 | 15 | =head2 Synopsis 16 | 17 | % prove 090-tap.t 18 | 19 | =head2 Description 20 | 21 | =cut 22 | 23 | ]] 24 | 25 | require'test_assertion' 26 | 27 | plan(3) 28 | truthy( true, 'truthy' ) 29 | equals( 42, 42, '42 == 42' ) 30 | passes( 'pass' ) 31 | 32 | -- Local Variables: 33 | -- mode: lua 34 | -- lua-indent-level: 4 35 | -- fill-column: 100 36 | -- End: 37 | -- vim: ft=lua expandtab shiftwidth=4: 38 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/091-profile.t: -------------------------------------------------------------------------------- 1 | #! /usr/bin/lua 2 | -- 3 | -- lua-Harness : 4 | -- 5 | -- Copyright (C) 2018-2021, Perrad Francois 6 | -- 7 | -- This code is licensed under the terms of the MIT/X11 license, 8 | -- like Lua itself. 9 | -- 10 | 11 | --[[ 12 | 13 | =head1 Lua test suite 14 | 15 | =head2 Synopsis 16 | 17 | % prove 091-profile.t 18 | 19 | =head2 Description 20 | 21 | =cut 22 | 23 | ]] 24 | 25 | require'test_assertion' 26 | 27 | plan'no_plan' 28 | 29 | is_string(_VERSION, "variable _VERSION") 30 | matches(_VERSION, '^Lua 5%.%d$') 31 | 32 | if jit then 33 | is_number(jit.version_num, "variable jit.version_num") 34 | end 35 | 36 | require_ok'profile' 37 | 38 | done_testing() 39 | 40 | -- Local Variables: 41 | -- mode: lua 42 | -- lua-indent-level: 4 43 | -- fill-column: 100 44 | -- End: 45 | -- vim: ft=lua expandtab shiftwidth=4: 46 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/lexico53/lexico.t: -------------------------------------------------------------------------------- 1 | -- 2 | -- lua-Harness : 3 | -- 4 | -- Copyright (C) 2015-2021, Perrad Francois 5 | -- 6 | -- This code is licensed under the terms of the MIT/X11 license, 7 | -- like Lua itself. 8 | -- 9 | 10 | equals("\u{41}", "A") 11 | equals("\u{20AC}", "\xE2\x82\xAC") 12 | equals("\u{20ac}", "\xe2\x82\xac") 13 | 14 | do 15 | local f, msg = load [[a = "A\u{yz}"]] 16 | matches(msg, "^[^:]+:%d+: .- near") 17 | 18 | f, msg = load [[a = "A\u{41"]] 19 | matches(msg, "^[^:]+:%d+: .- near") 20 | 21 | f, msg = load [[a = "A\u{FFFFFFFFFF}"]] 22 | matches(msg, "^[^:]+:%d+: .- near") 23 | end 24 | 25 | -- Local Variables: 26 | -- mode: lua 27 | -- lua-indent-level: 4 28 | -- fill-column: 100 29 | -- End: 30 | -- vim: ft=lua expandtab shiftwidth=4: 31 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/lexico54/lexico.t: -------------------------------------------------------------------------------- 1 | -- 2 | -- lua-Harness : 3 | -- 4 | -- Copyright (C) 2019-2021, Perrad Francois 5 | -- 6 | -- This code is licensed under the terms of the MIT/X11 license, 7 | -- like Lua itself. 8 | -- 9 | 10 | equals("\u{10000}", "\xF0\x90\x80\x80") 11 | equals("\u{200000}", "\xF8\x88\x80\x80\x80") 12 | equals("\u{4000000}", "\xFC\x84\x80\x80\x80\x80") 13 | 14 | -- Local Variables: 15 | -- mode: lua 16 | -- lua-indent-level: 4 17 | -- fill-column: 100 18 | -- End: 19 | -- vim: ft=lua expandtab shiftwidth=4: 20 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/lexico54/metatable.t: -------------------------------------------------------------------------------- 1 | -- 2 | -- lua-Harness : 3 | -- 4 | -- Copyright (C) 2019-2021, Perrad Francois 5 | -- 6 | -- This code is licensed under the terms of the MIT/X11 license, 7 | -- like Lua itself. 8 | -- 9 | 10 | do -- toclose 11 | local called = false 12 | do 13 | local foo = setmetatable({}, { __close = function () called = true end }) 14 | is_table(foo, "toclose") 15 | is_false(called) 16 | end 17 | is_true(called) 18 | 19 | error_matches(function () do local foo = {} end end, 20 | "^[^:]+:%d+: variable 'foo' got a non%-closable value") 21 | 22 | not_errors(function () 23 | local var1 = nil 24 | local var2 = nil 25 | do 26 | local var3 = setmetatable({}, { __close = function () end }) 27 | end 28 | local var4 = true 29 | -- attempt to close non-closable variable 'var4' 30 | end, "blocker bug 5.4.0-rc3") 31 | end 32 | 33 | -- Local Variables: 34 | -- mode: lua 35 | -- lua-indent-level: 4 36 | -- fill-column: 100 37 | -- End: 38 | -- vim: ft=lua expandtab shiftwidth=4: 39 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/lexicojit/basic.t: -------------------------------------------------------------------------------- 1 | -- 2 | -- lua-Harness : 3 | -- 4 | -- Copyright (C) 2018-2021, Perrad Francois 5 | -- 6 | -- This code is licensed under the terms of the MIT/X11 license, 7 | -- like Lua itself. 8 | -- 9 | 10 | do -- tonumber 11 | equals(tonumber(42uLL), 42, "function tonumber (cdata)") 12 | equals(tonumber(42LL), 42) 13 | end 14 | 15 | do -- tostring 16 | equals(tostring(42uLL), '42ULL', "function tostring (cdata)") 17 | equals(tostring(42LL), '42LL') 18 | equals(tostring(1i), '0+1i') 19 | equals(tostring(12.5i), '0+12.5i') 20 | end 21 | 22 | -- Local Variables: 23 | -- mode: lua 24 | -- lua-indent-level: 4 25 | -- fill-column: 100 26 | -- End: 27 | -- vim: ft=lua expandtab shiftwidth=4: 28 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/lexicojit/lexico.t: -------------------------------------------------------------------------------- 1 | -- 2 | -- lua-Harness : 3 | -- 4 | -- Copyright (C) 2018-2021, Perrad Francois 5 | -- 6 | -- This code is licensed under the terms of the MIT/X11 license, 7 | -- like Lua itself. 8 | -- 9 | 10 | is_cdata(42LL, "42LL") 11 | is_cdata(42ULL, "42ULL") 12 | is_cdata(42uLL, "42uLL") 13 | is_cdata(42ull, "42ull") 14 | 15 | is_cdata(0x2aLL, "0x2aLL") 16 | is_cdata(0x2aULL, "0x2aULL") 17 | is_cdata(0x2auLL, "0x2auLL") 18 | is_cdata(0x2aull, "0x2aull") 19 | 20 | is_cdata(12.5i, '12.5i') 21 | is_cdata(12.5I, '12.5I') 22 | is_cdata(1i, '1i') 23 | is_cdata(1I, '1I') 24 | is_cdata(0i, '0i') 25 | is_cdata(0I, '0I') 26 | 27 | -- Local Variables: 28 | -- mode: lua 29 | -- lua-indent-level: 4 30 | -- fill-column: 100 31 | -- End: 32 | -- vim: ft=lua expandtab shiftwidth=4: 33 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | --[[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = true, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = true, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = true, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | compat53 = false, 31 | --[[ 32 | has_math_log10 = true, 33 | has_mathx = true, 34 | has_metamethod_ipairs = true, 35 | --]] 36 | 37 | --[[ luajit 38 | luajit_compat52 = true, 39 | openresty = false, 40 | --]] 41 | 42 | } 43 | 44 | package.loaded.profile = profile -- prevents loading of default profile 45 | 46 | return profile 47 | 48 | -- 49 | -- Copyright (c) 2018-2019 Francois Perrad 50 | -- 51 | -- This library is licensed under the terms of the MIT/X11 license, 52 | -- like Lua itself. 53 | -- 54 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_lua51.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | -- [[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = false, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = false, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = true, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | --[[ luajit 31 | luajit_compat52 = true, 32 | openresty = false, 33 | --]] 34 | 35 | } 36 | 37 | package.loaded.profile = profile -- prevents loading of default profile 38 | 39 | return profile 40 | 41 | -- 42 | -- Copyright (c) 2018-2019 Francois Perrad 43 | -- 44 | -- This library is licensed under the terms of the MIT/X11 license, 45 | -- like Lua itself. 46 | -- 47 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_lua51_strict.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | --[[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = false, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = false, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = true, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | --[[ luajit 31 | luajit_compat52 = true, 32 | openresty = false, 33 | --]] 34 | 35 | } 36 | 37 | package.loaded.profile = profile -- prevents loading of default profile 38 | 39 | return profile 40 | 41 | -- 42 | -- Copyright (c) 2018-2019 Francois Perrad 43 | -- 44 | -- This library is licensed under the terms of the MIT/X11 license, 45 | -- like Lua itself. 46 | -- 47 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_lua52.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | --[[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = true, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = false, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = true, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | --[[ luajit 31 | luajit_compat52 = true, 32 | openresty = false, 33 | --]] 34 | 35 | } 36 | 37 | package.loaded.profile = profile -- prevents loading of default profile 38 | 39 | return profile 40 | 41 | -- 42 | -- Copyright (c) 2018-2019 Francois Perrad 43 | -- 44 | -- This library is licensed under the terms of the MIT/X11 license, 45 | -- like Lua itself. 46 | -- 47 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_lua52_strict.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | --[[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = false, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = false, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = true, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | --[[ luajit 31 | luajit_compat52 = true, 32 | openresty = false, 33 | --]] 34 | 35 | } 36 | 37 | package.loaded.profile = profile -- prevents loading of default profile 38 | 39 | return profile 40 | 41 | -- 42 | -- Copyright (c) 2018-2019 Francois Perrad 43 | -- 44 | -- This library is licensed under the terms of the MIT/X11 license, 45 | -- like Lua itself. 46 | -- 47 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_lua53.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | --[[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = false, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = true, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = true, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | compat53 = false, 31 | --[[ 32 | has_mathx = true, 33 | has_metamethod_ipairs = true, 34 | --]] 35 | 36 | --[[ luajit 37 | luajit_compat52 = true, 38 | openresty = false, 39 | --]] 40 | 41 | } 42 | 43 | package.loaded.profile = profile -- prevents loading of default profile 44 | 45 | return profile 46 | 47 | -- 48 | -- Copyright (c) 2018-2019 Francois Perrad 49 | -- 50 | -- This library is licensed under the terms of the MIT/X11 license, 51 | -- like Lua itself. 52 | -- 53 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_lua53_noconv.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | --[[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = false, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = true, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = true, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | nocvtn2s = true, 31 | nocvts2n = true, 32 | 33 | compat53 = false, 34 | --[[ 35 | has_mathx = true, 36 | has_metamethod_ipairs = true, 37 | --]] 38 | 39 | --[[ luajit 40 | luajit_compat52 = true, 41 | openresty = false, 42 | --]] 43 | 44 | } 45 | 46 | package.loaded.profile = profile -- prevents loading of default profile 47 | 48 | return profile 49 | 50 | -- 51 | -- Copyright (c) 2018-2019 Francois Perrad 52 | -- 53 | -- This library is licensed under the terms of the MIT/X11 license, 54 | -- like Lua itself. 55 | -- 56 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_lua53_strict.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | --[[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = false, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = false, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = true, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | compat53 = false, 31 | --[[ 32 | has_mathx = true, 33 | has_metamethod_ipairs = true, 34 | --]] 35 | 36 | --[[ luajit 37 | luajit_compat52 = true, 38 | openresty = false, 39 | --]] 40 | 41 | } 42 | 43 | package.loaded.profile = profile -- prevents loading of default profile 44 | 45 | return profile 46 | 47 | -- 48 | -- Copyright (c) 2018-2019 Francois Perrad 49 | -- 50 | -- This library is licensed under the terms of the MIT/X11 license, 51 | -- like Lua itself. 52 | -- 53 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_lua54.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | --[[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = false, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = false, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = true, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | compat53 = true, 31 | --[[ 32 | has_mathx = true, 33 | has_metamethod_ipairs = true, 34 | --]] 35 | 36 | --[[ luajit 37 | luajit_compat52 = true, 38 | openresty = false, 39 | --]] 40 | 41 | } 42 | 43 | package.loaded.profile = profile -- prevents loading of default profile 44 | 45 | return profile 46 | 47 | -- 48 | -- Copyright (c) 2018-2019 Francois Perrad 49 | -- 50 | -- This library is licensed under the terms of the MIT/X11 license, 51 | -- like Lua itself. 52 | -- 53 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_lua54_noconv.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | --[[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = false, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = false, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = true, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | nocvtn2s = true, 31 | nocvts2n = true, 32 | 33 | compat53 = true, 34 | --[[ 35 | has_mathx = true, 36 | has_metamethod_ipairs = true, 37 | --]] 38 | 39 | --[[ luajit 40 | luajit_compat52 = true, 41 | openresty = false, 42 | --]] 43 | 44 | } 45 | 46 | package.loaded.profile = profile -- prevents loading of default profile 47 | 48 | return profile 49 | 50 | -- 51 | -- Copyright (c) 2018-2019 Francois Perrad 52 | -- 53 | -- This library is licensed under the terms of the MIT/X11 license, 54 | -- like Lua itself. 55 | -- 56 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_lua54_strict.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | --[[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = false, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = false, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = true, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | compat53 = false, 31 | --[[ 32 | has_math_log10 = true, 33 | has_mathx = true, 34 | has_metamethod_ipairs = true, 35 | --]] 36 | 37 | --[[ luajit 38 | luajit_compat52 = true, 39 | openresty = false, 40 | --]] 41 | 42 | } 43 | 44 | package.loaded.profile = profile -- prevents loading of default profile 45 | 46 | return profile 47 | 48 | -- 49 | -- Copyright (c) 2018-2019 Francois Perrad 50 | -- 51 | -- This library is licensed under the terms of the MIT/X11 license, 52 | -- like Lua itself. 53 | -- 54 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_luajit20.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | -- [[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = false, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = false, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = true, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | compat53 = false, 31 | --[[ 32 | has_math_log10 = true, 33 | has_mathx = true, 34 | has_metamethod_ipairs = true, 35 | --]] 36 | 37 | -- [[ luajit 38 | luajit_compat52 = false, 39 | openresty = false, 40 | --]] 41 | 42 | } 43 | 44 | package.loaded.profile = profile -- prevents loading of default profile 45 | 46 | return profile 47 | 48 | -- 49 | -- Copyright (c) 2018-2019 Francois Perrad 50 | -- 51 | -- This library is licensed under the terms of the MIT/X11 license, 52 | -- like Lua itself. 53 | -- 54 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_luajit20_compat52.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | --[[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = false, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = false, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = false, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | compat53 = false, 31 | --[[ 32 | has_math_log10 = true, 33 | has_mathx = true, 34 | has_metamethod_ipairs = true, 35 | --]] 36 | 37 | -- [[ luajit 38 | luajit_compat52 = true, 39 | openresty = false, 40 | --]] 41 | 42 | } 43 | 44 | package.loaded.profile = profile -- prevents loading of default profile 45 | 46 | return profile 47 | 48 | -- 49 | -- Copyright (c) 2018-2019 Francois Perrad 50 | -- 51 | -- This library is licensed under the terms of the MIT/X11 license, 52 | -- like Lua itself. 53 | -- 54 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_luajit21.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | --[[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = false, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = false, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = true, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | compat53 = false, 31 | --[[ 32 | has_math_log10 = true, 33 | has_mathx = true, 34 | has_metamethod_ipairs = true, 35 | --]] 36 | 37 | -- [[ luajit 38 | luajit_compat52 = false, 39 | openresty = false, 40 | --]] 41 | 42 | } 43 | 44 | package.loaded.profile = profile -- prevents loading of default profile 45 | 46 | return profile 47 | 48 | -- 49 | -- Copyright (c) 2018-2019 Francois Perrad 50 | -- 51 | -- This library is licensed under the terms of the MIT/X11 license, 52 | -- like Lua itself. 53 | -- 54 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_luajit21_compat52.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | --[[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = false, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = false, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = false, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | compat53 = false, 31 | --[[ 32 | has_math_log10 = true, 33 | has_mathx = true, 34 | has_metamethod_ipairs = true, 35 | --]] 36 | 37 | -- [[ luajit 38 | luajit_compat52 = true, 39 | openresty = false, 40 | --]] 41 | 42 | } 43 | 44 | package.loaded.profile = profile -- prevents loading of default profile 45 | 46 | return profile 47 | 48 | -- 49 | -- Copyright (c) 2018-2019 Francois Perrad 50 | -- 51 | -- This library is licensed under the terms of the MIT/X11 license, 52 | -- like Lua itself. 53 | -- 54 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/profile_openresty.lua: -------------------------------------------------------------------------------- 1 | --- 2 | -- lua-Harness : 3 | --- 4 | 5 | local profile = { 6 | 7 | --[[ compat 5.0 8 | has_string_gfind = true, 9 | has_math_mod = true, 10 | --]] 11 | 12 | compat51 = false, 13 | --[[ 14 | has_unpack = true, 15 | has_package_loaders = true, 16 | has_math_log10 = true, 17 | has_loadstring = true, 18 | has_table_maxn = true, 19 | has_module = true, 20 | has_package_seeall = true, 21 | --]] 22 | 23 | compat52 = false, 24 | --[[ 25 | has_mathx = true, 26 | has_bit32 = false, 27 | has_metamethod_ipairs = true, 28 | --]] 29 | 30 | compat53 = false, 31 | --[[ 32 | has_math_log10 = true, 33 | has_mathx = true, 34 | has_metamethod_ipairs = true, 35 | --]] 36 | 37 | -- [[ luajit 38 | luajit_compat52 = true, 39 | openresty = true, 40 | --]] 41 | 42 | } 43 | 44 | package.loaded.profile = profile -- prevents loading of default profile 45 | 46 | return profile 47 | 48 | -- 49 | -- Copyright (c) 2018-2019 Francois Perrad 50 | -- 51 | -- This library is licensed under the terms of the MIT/X11 license, 52 | -- like Lua itself. 53 | -- 54 | -------------------------------------------------------------------------------- /test/lua-Harness-tests/rx_captures: -------------------------------------------------------------------------------- 1 | (a.)..(..) zzzabcdefzzz ab\tef basic match 2 | (a(b(c))(d)) abcd abcd\tbc\tc\td nested match 3 | ((%w+)) abcd abcd\tabcd nested match 4 | (a*(.)%w(%s*)) aa!b c aa!b \t!\t nested match 5 | (a?).. abcd a opt 6 | (A?).. abcd '' opt 7 | ()aa() flaaap 3\t5 empty capture 8 | (.)%1 bookkeeper o backreference 9 | (%w+)%s+%1 hello hello hello backreference 10 | (.*)x 123x 123 repeated dot capture 11 | $(%w+) $abc= abc not escaped 12 | 13 | ## vim: noexpandtab tabstop=4 shiftwidth=4 14 | -------------------------------------------------------------------------------- /test/luajit-test-init.lua: -------------------------------------------------------------------------------- 1 | -- XXX: PUC Rio Lua 5.1 test suite checks that global variable 2 | -- `_loadfile()` exists and uses it for code loading from test 3 | -- files. If the variable is not defined then suite uses 4 | -- `loadfile()` as default. Same for the `_dofile()`. 5 | -- lua-Harness also uses the same implementation of `dofile()` 6 | -- for the same reason. 7 | 8 | -- XXX: Some tests in PUC Rio Lua 5.1 test suite clean `arg` 9 | -- variable, so evaluate this once and use later. 10 | local path_to_sources = arg[0] and arg[0]:gsub("[^/]+$", "") or "" 11 | 12 | -- luacheck: no global 13 | function _loadfile(filename) 14 | return loadfile(path_to_sources..filename) 15 | end 16 | 17 | -- luacheck: no global 18 | function _dofile(filename) 19 | return dofile(path_to_sources..filename) 20 | end 21 | -------------------------------------------------------------------------------- /test/tarantool-c-tests/fix-yield-c-hook-script.lua: -------------------------------------------------------------------------------- 1 | -- Auxiliary script to provide Lua functions to be used in the 2 | -- test . 3 | local M = {} 4 | 5 | -- The function to call, when line hook (calls `lua_yield()`) is 6 | -- set. 7 | M.yield_in_c_hook = function() 8 | local co = coroutine.create(function() 9 | -- Just some payload, don't really matter. 10 | local _ = tostring(1) 11 | end) 12 | -- Enter coroutine and yield from the 1st line. 13 | coroutine.resume(co) 14 | -- Try to get the PC to return and continue to execute the first 15 | -- line (it will still yield from the hook). 16 | coroutine.resume(co) 17 | end 18 | 19 | return M 20 | -------------------------------------------------------------------------------- /test/tarantool-c-tests/lj-991-fix-finalizer-error-handler-init.test.c: -------------------------------------------------------------------------------- 1 | #include "lua.h" 2 | #include "test.h" 3 | #include "utils.h" 4 | 5 | /* 6 | * This test demonstrates an uncleared Lua stack after the 7 | * initialization of the error handler for GC finalizers. 8 | * See https://github.com/luajit/luajit/issues/991 for 9 | * details. 10 | */ 11 | 12 | static int stack_is_clean(void *test_state) 13 | { 14 | lua_State *L = test_state; 15 | assert_true(lua_gettop(L) == 0); 16 | return TEST_EXIT_SUCCESS; 17 | } 18 | 19 | int main(void) 20 | { 21 | lua_State *L = utils_lua_init(); 22 | 23 | const struct test_unit tgroup[] = { 24 | test_unit_def(stack_is_clean) 25 | }; 26 | 27 | const int test_result = test_run_group(tgroup, L); 28 | utils_lua_close(L); 29 | return test_result; 30 | } 31 | -------------------------------------------------------------------------------- /test/tarantool-c-tests/misclib-sysprof-capi-script.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -- luacheck: no global 4 | assert(c_payload, 'c_payload global function should be set via script loader') 5 | 6 | local function lua_payload(n) 7 | if n <= 1 then 8 | return n 9 | end 10 | return lua_payload(n - 1) + lua_payload(n - 2) 11 | end 12 | 13 | local function payload() 14 | local n_iterations = 500000 15 | 16 | local co = coroutine.create(function() 17 | for i = 1, n_iterations do 18 | if i % 2 == 0 then 19 | c_payload(10) 20 | else 21 | lua_payload(10) 22 | end 23 | coroutine.yield() 24 | end 25 | end) 26 | 27 | for _ = 1, n_iterations do 28 | coroutine.resume(co) 29 | end 30 | end 31 | 32 | M.profile_func_jiton = payload 33 | M.profile_func_jitoff = payload 34 | 35 | return M 36 | -------------------------------------------------------------------------------- /test/tarantool-c-tests/unit-tap.test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | static int test_ok(void *test_state) 4 | { 5 | UNUSED(test_state); 6 | return TEST_EXIT_SUCCESS; 7 | } 8 | 9 | static int test_skip(void *test_state) 10 | { 11 | UNUSED(test_state); 12 | return skip("test skip"); 13 | } 14 | 15 | static int test_todo(void *test_state) 16 | { 17 | UNUSED(test_state); 18 | return todo("test todo"); 19 | } 20 | 21 | int main(void) 22 | { 23 | const struct test_unit tgroup[] = { 24 | test_unit_def(test_ok), 25 | test_unit_def(test_skip), 26 | test_unit_def(test_todo) 27 | }; 28 | return test_run_group(tgroup, NULL); 29 | } 30 | -------------------------------------------------------------------------------- /test/tarantool-tests/bc-jit-unpatching.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('bc-jit-unpatching'):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | }) 5 | 6 | test:plan(1) 7 | 8 | local utils = require('utils') 9 | -- Function with up-recursion. 10 | local function f(n) 11 | return n < 2 and n or f(n - 1) + f(n - 2) 12 | end 13 | 14 | local ret1bc = 'RET1%s*1%s*2' 15 | -- Check that this bytecode still persists. 16 | assert(utils.frontend.hasbc(load(string.dump(f)), ret1bc)) 17 | 18 | jit.opt.start('hotloop=1', 'hotexit=1') 19 | -- Compile function to get JLOOP bytecode in recursion. 20 | f(5) 21 | 22 | test:ok(utils.frontend.hasbc(load(string.dump(f)), ret1bc), 23 | 'bytecode unpatching is OK') 24 | 25 | test:done(true) 26 | -------------------------------------------------------------------------------- /test/tarantool-tests/c-library-path-length.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('c-library-path-length') 3 | test:plan(2) 4 | 5 | -- It doesn't really matter how long that 6 | -- string is, if it is longer than 4096. 7 | local long_path = string.rep('/path', 1024) 8 | package.cpath = long_path 9 | 10 | local res, err = package.loadlib(long_path, 'func') 11 | test:ok(res == nil, 'loaded library with a too large path') 12 | test:like(err, 'path too long', 'incorrect error') 13 | 14 | test:done(true) 15 | -------------------------------------------------------------------------------- /test/tarantool-tests/ffi-ccall/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | BuildTestCLib(libfficcall libfficcall.c ffi-ccall-arm64-fp-convention.test.lua) 2 | -------------------------------------------------------------------------------- /test/tarantool-tests/ffi-ccall/libfficcall.c: -------------------------------------------------------------------------------- 1 | struct sz12_t { 2 | float f1; 3 | float f2; 4 | float f3; 5 | }; 6 | 7 | struct sz12_t retsz12(struct sz12_t a) 8 | { 9 | return a; 10 | } 11 | 12 | struct sz12_t sum2sz12(struct sz12_t a, struct sz12_t b) 13 | { 14 | struct sz12_t res = {0}; 15 | res.f1 = a.f1 + b.f1; 16 | res.f2 = a.f2 + b.f2; 17 | res.f3 = a.f3 + b.f3; 18 | return res; 19 | } 20 | 21 | struct sz12_t sum3sz12(struct sz12_t a, struct sz12_t b, struct sz12_t c) 22 | { 23 | struct sz12_t res = {0}; 24 | res.f1 = a.f1 + b.f1 + c.f1; 25 | res.f2 = a.f2 + b.f2 + c.f2; 26 | res.f3 = a.f3 + b.f3 + c.f3; 27 | return res; 28 | } 29 | -------------------------------------------------------------------------------- /test/tarantool-tests/ffi-tabov.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local ffi = require('ffi') 3 | 4 | -- This test is moved here from the LuaJIT-tests suite since it 5 | -- should be run separately because it exhausts the ctype table. 6 | local test = tap.test('ffi-tabov') 7 | 8 | test:plan(3) 9 | 10 | -- XXX: Amount of ctypes available to the user of a platform. 11 | -- Was declared in the LuaJIT-tests suite. 12 | local MIN_AVAILABLE_CTYPES = 20000 13 | -- Maximum available amount of ctypes. 14 | local CTID_MAX = 2^16 15 | 16 | local last = 0 17 | 18 | local res, errmsg = pcall(function() 19 | for i = 1, CTID_MAX do 20 | last = i 21 | ffi.typeof('struct {}') 22 | end 23 | end) 24 | 25 | test:ok(res == false, 'correct status') 26 | test:like(errmsg, 'table overflow', 'correct error message') 27 | 28 | test:ok(last > MIN_AVAILABLE_CTYPES, 'huge enough amount of free ctypes') 29 | 30 | test:done(true) 31 | -------------------------------------------------------------------------------- /test/tarantool-tests/fix-argv-handling.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('fix-argv-handling'):skipcond({ 3 | ['DYLD_INSERT_LIBRARIES does not work on macOS'] = jit.os == 'OSX', 4 | ['Skipped for static build'] = os.getenv('LUAJIT_BUILDMODE') ~= 'dynamic', 5 | }) 6 | 7 | test:plan(1) 8 | 9 | -- XXX: Since the Linux kernel 5.18-rc1 release, `argv` is forced 10 | -- to a single empty string if it is empty [1], so the issue is 11 | -- not reproducible on new kernels. 12 | -- 13 | -- luacheck: push no max_comment_line_length 14 | -- 15 | -- [1]: https://lore.kernel.org/all/20220201000947.2453721-1-keescook@chromium.org/ 16 | -- 17 | -- luacheck: pop 18 | 19 | local utils = require('utils') 20 | local execlib = require('execlib') 21 | local cmd = utils.exec.luabin(arg) 22 | 23 | -- Start the LuaJIT with an empty argv array and mocked 24 | -- `luaL_newstate`. 25 | local output = execlib.empty_argv_exec(cmd) 26 | 27 | -- Without the patch, the test fails with a segmentation fault 28 | -- instead of returning an error. 29 | test:like(output, 'cannot create state', 'correct argv handling') 30 | test:done(true) 31 | -------------------------------------------------------------------------------- /test/tarantool-tests/fix-argv-handling/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) 2 | BuildTestCLib(mynewstate mynewstate.c ${test_name}.test.lua) 3 | BuildTestCLib(execlib execlib.c ${test_name}.test.lua) 4 | -------------------------------------------------------------------------------- /test/tarantool-tests/fix-argv-handling/mynewstate.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct lua_State; 4 | 5 | /* Error-injected mock. */ 6 | struct lua_State *luaL_newstate(void) 7 | { 8 | return NULL; 9 | } 10 | -------------------------------------------------------------------------------- /test/tarantool-tests/fix-argv2ctype-cts-L-init.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('fix-argv2ctype-cts-L-init'):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | }) 5 | 6 | -- Loading of 'tap' module initialize `cts->L` during parsing. 7 | -- Run standalone script for testing. 8 | local script = require('utils').exec.makecmd(arg) 9 | 10 | test:plan(1) 11 | 12 | local output = script() 13 | test:is(output, 'OK', 'correct recording with uninitialized cts->L') 14 | 15 | test:done(true) 16 | -------------------------------------------------------------------------------- /test/tarantool-tests/fix-argv2ctype-cts-L-init/script.lua: -------------------------------------------------------------------------------- 1 | local ffi = require('ffi') 2 | 3 | jit.opt.start('hotloop=1') 4 | 5 | local i = 1 6 | -- Use `while` to start compilation of the trace at the first 7 | -- iteration, before `ffi.new()` is called, so `cts->L` is 8 | -- uninitialized. 9 | while i < 3 do 10 | ffi.new('uint64_t', i) 11 | i = i + 1 12 | end 13 | 14 | print('OK') 15 | -------------------------------------------------------------------------------- /test/tarantool-tests/fix-binary-number-parsing.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate incorrect behaviour of binary number 4 | -- parsing with fractional dot. 5 | -- See also: 6 | -- luacheck: push no max_comment_line_length 7 | -- https://www.freelists.org/post/luajit/Fractional-binary-number-literals 8 | -- luacheck: pop 9 | local test = tap.test('fix-binary-number-parsing') 10 | test:plan(2) 11 | 12 | -- Test that an incorrect literal with a non-0 fractional part 13 | -- still can't be converted to a number. 14 | test:is(tonumber('0b.1'), nil, '0b.1 is not converted') 15 | -- Test that an incorrect literal with 0 fractional part can't be 16 | -- converted to a number. 17 | test:is(tonumber('0b.0'), nil, '0b.0 is not converted') 18 | 19 | test:done(true) 20 | -------------------------------------------------------------------------------- /test/tarantool-tests/fix-bit-shift-dualnum.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate LuaJIT misbehaviour for bitshift 4 | -- operations in DUALNUM mode. 5 | -- See also: 6 | -- https://www.freelists.org/post/luajit/dead-loop-in-bitrshift. 7 | 8 | local test = tap.test('fix-bit-shift-dualnum') 9 | test:plan(5) 10 | 11 | -- This produces the number (not integer) `TValue` type for the 12 | -- DUALNUM build. If the second parameter of any of the shift 13 | -- functions is not an integer in the DUALNUM build, LuaJIT tries 14 | -- to convert it to an integer. In the case of a number, it does 15 | -- nothing and endlessly retries the call to the fallback 16 | -- function. 17 | local SHIFT_V = 1 - '0' 18 | 19 | -- Any of the shift calls below causes the infinite FFH retrying 20 | -- loop before the patch. 21 | test:ok(bit.arshift(0, SHIFT_V), 0, 'no infifnite loop in bit.arshift') 22 | test:ok(bit.lshift(0, SHIFT_V), 0, 'no infifnite loop in bit.lshift') 23 | test:ok(bit.rshift(0, SHIFT_V), 0, 'no infifnite loop in bit.rshift') 24 | test:ok(bit.rol(0, SHIFT_V), 0, 'no infifnite loop in bit.rol') 25 | test:ok(bit.ror(0, SHIFT_V), 0, 'no infifnite loop in bit.ror') 26 | 27 | test:done(true) 28 | -------------------------------------------------------------------------------- /test/tarantool-tests/fix-bit-shift-generation/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) 2 | BuildTestCLib(libtestbitshift libtestbitshift.c ${test_name}.test.lua) 3 | -------------------------------------------------------------------------------- /test/tarantool-tests/fix-bit-shift-generation/libtestbitshift.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | uint64_t 4 | pick4(const int arg1, const int arg2, const int arg3, const uint64_t arg4) 5 | { 6 | return arg4; 7 | } 8 | -------------------------------------------------------------------------------- /test/tarantool-tests/fix-cdata-concat.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate incorrect behaviour of cdata 4 | -- concatenation in LuaJIT. 5 | -- See also 6 | -- https://www.freelists.org/post/luajit/cdata-concatenation. 7 | local test = tap.test('cdata-concat') 8 | test:plan(2) 9 | 10 | local r, e = pcall(function() 11 | return 1LL .. 2LL 12 | end) 13 | test:ok(not r and e:match('attempt to concatenate'), 'cdata concatenation') 14 | 15 | -- Check, that concatenation work, when metamethod is defined. 16 | debug.getmetatable(1LL).__concat = function(a, b) 17 | return tostring(a) .. tostring(b) 18 | end 19 | test:ok(1LL .. 2LL == '1LL2LL', 'cdata concatenation with defined metamethod') 20 | 21 | test:done(true) 22 | -------------------------------------------------------------------------------- /test/tarantool-tests/fix-fold-simplify-conv-sext.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('fix-fold-simplify-conv-sext'):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | }) 5 | 6 | local NSAMPLES = 4 7 | local NTEST = NSAMPLES * 2 - 1 8 | test:plan(NTEST) 9 | 10 | local ffi = require('ffi') 11 | local samples = ffi.new('int [?]', NSAMPLES) 12 | 13 | -- Prepare data. 14 | for i = 0, NSAMPLES - 1 do samples[i] = i end 15 | 16 | local expected = {3, 2, 1, 0, 3, 2, 1} 17 | 18 | local START = 3 19 | local STOP = -START 20 | 21 | local results = {} 22 | jit.opt.start('hotloop=1') 23 | for i = START, STOP, -1 do 24 | -- While recording cdata indexing the fold CONV SEXT 25 | -- optimization eliminate sign extension for the corresponding 26 | -- non constant value (i.e. stack slot). As a result the read 27 | -- out of bounds was occurring. 28 | results[#results + 1] = samples[i % NSAMPLES] 29 | end 30 | 31 | for i = 1, NTEST do 32 | test:ok(results[i] == expected[i], 'correct cdata indexing') 33 | end 34 | 35 | test:done(true) 36 | -------------------------------------------------------------------------------- /test/tarantool-tests/gh-3196-incorrect-string-length.test.lua: -------------------------------------------------------------------------------- 1 | -- Miscellaneous test for LuaJIT bugs 2 | local tap = require('tap') 3 | 4 | local test = tap.test("gh-3196-incorrect-string-length") 5 | test:plan(2) 6 | -- 7 | -- gh-3196: incorrect string length if Lua hash returns 0 8 | -- 9 | -- luacheck: push no max_line_length 10 | -- 11 | local h = "\x1F\x93\xE2\x1C\xCA\xDE\x28\x08\x26\x01\xED\x0A\x2F\xE4\x21\x02\x97\x77\xD9\x3E" 12 | test:is(h:len(), 20) 13 | 14 | h = "\x0F\x93\xE2\x1C\xCA\xDE\x28\x08\x26\x01\xED\x0A\x2F\xE4\x21\x02\x97\x77\xD9\x3E" 15 | test:is(h:len(), 20) 16 | -- luacheck: pop 17 | 18 | test:done(true) 19 | -------------------------------------------------------------------------------- /test/tarantool-tests/gh-4427-ffi-sandwich/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) 2 | BuildTestCLib(libsandwich libsandwich.c ${test_name}.test.lua) 3 | -------------------------------------------------------------------------------- /test/tarantool-tests/gh-4427-ffi-sandwich/script.lua: -------------------------------------------------------------------------------- 1 | local hotloop = assert(arg[1], 'hotloop argument is missing') 2 | local trigger = assert(arg[2], 'trigger argument is missing') 3 | 4 | local ffi = require('ffi') 5 | local ffisandwich = ffi.load('libsandwich') 6 | ffi.cdef('int increment(struct sandwich *state, int i)') 7 | 8 | -- Save the current coroutine and set the value to trigger 9 | -- call the Lua routine instead of C implementation. 10 | local sandwich = require('libsandwich')(trigger) 11 | 12 | -- Depending on trigger and hotloop values the following contexts 13 | -- are possible: 14 | -- * if trigger <= hotloop -> trace recording is aborted 15 | -- * if trigger > hotloop -> trace is recorded but execution 16 | -- leads to panic 17 | jit.opt.start(string.format('hotloop=%d', hotloop)) 18 | 19 | local res 20 | for i = 0, hotloop + trigger do 21 | res = ffisandwich.increment(sandwich, i) 22 | end 23 | -- Check the resulting value if panic didn't occur earlier. 24 | assert(res == hotloop + trigger + 1, 'res is calculated correctly') 25 | io.write('#4427 still works') 26 | -------------------------------------------------------------------------------- /test/tarantool-tests/gh-4773-tonumber-fail-on-NUL-char.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | local test = tap.test("Tarantool 4773") 4 | test:plan(3) 5 | 6 | -- Test file to demonstrate LuaJIT tonumber routine fails on NUL 7 | -- char, details: 8 | -- https://github.com/tarantool/tarantool/issues/4773 9 | 10 | local t = { 11 | zero = '0', 12 | null = '\x00', 13 | tail = 'imun', 14 | } 15 | 16 | -- Since VM, Lua/C API and compiler use a single routine for 17 | -- conversion numeric string to a number, test cases are reduced 18 | -- to the following: 19 | test:is(tonumber(t.zero), 0) 20 | test:is(tonumber(t.zero .. t.tail), nil) 21 | test:is(tonumber(t.zero .. t.null .. t.tail), nil) 22 | 23 | test:done(true) 24 | -------------------------------------------------------------------------------- /test/tarantool-tests/gh-6065-jit-library-smoke-tests.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('gh-6065-jit-library-smoke-tests'):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | }) 5 | 6 | test:plan(1) 7 | 8 | -- Just check whether LuaJIT is built with JIT support. Otherwise, 9 | -- raises an error that is handled via and passed 10 | -- as a second argument to the assertion. 11 | test:ok(pcall(jit.on)) 12 | 13 | test:done(true) 14 | -------------------------------------------------------------------------------- /test/tarantool-tests/gh-6084-missed-carg1-in-bctsetr-fallback.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local utils = require('utils') 3 | 4 | local test = tap.test('gh-6084-missed-carg1-in-bctsetr-fallback') 5 | test:plan(2) 6 | 7 | -- XXX: Bytecode TSETR appears only in built-ins libraries, when 8 | -- doing fixups for fast function written in Lua (i.e. 9 | -- `table.move()`), by replacing all TSETV bytecodes with 10 | -- the TSETR. See for more details. 11 | 12 | -- This test checks that fallback path, when the index of the new 13 | -- set element is greater than the table's asize, doesn't lead 14 | -- to a crash. 15 | 16 | -- XXX: We need to make sure the bytecode is present in the chosen 17 | -- built-in to make sure our test is still valid. 18 | assert(utils.frontend.hasbc(table.move, 'TSETR')) 19 | 20 | -- `t` table asize equals 1. Just copy its first element (1) 21 | -- to the field by index 2 > 1, to fallback inside TSETR. 22 | local t = {1} 23 | local res = table.move(t, 1, 1, 2) 24 | test:ok(t == res, 'table.move returns the same table') 25 | test:ok(t[1] == t[2], 'table.move is correct') 26 | 27 | test:done(true) 28 | -------------------------------------------------------------------------------- /test/tarantool-tests/gh-6096-external-unwinding-on-arm64.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to check correctness of external unwinding 4 | -- in LuaJIT. 5 | -- See also https://github.com/LuaJIT/LuaJIT/issues/698, 6 | -- https://github.com/LuaJIT/LuaJIT/pull/757. 7 | local test = tap.test('gh-6096-external-unwinding-on-arm64') 8 | test:plan(1) 9 | 10 | local res = pcall(require, 'not-existing-module') 11 | test:ok(res == false, 'successful unwinding in pcall') 12 | 13 | test:done(true) 14 | -------------------------------------------------------------------------------- /test/tarantool-tests/gh-6098-fix-side-exit-patching-on-arm64/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) 2 | BuildTestCLib(libproxy libproxy.c ${test_name}.test.lua) 3 | -------------------------------------------------------------------------------- /test/tarantool-tests/gh-6098-fix-side-exit-patching-on-arm64/libproxy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | * Function with the signature similar to Lua builtin, 6 | * that routes the flow through C frame. 7 | */ 8 | static int proxycall(lua_State *L) 9 | { 10 | lua_call(L, lua_gettop(L) - 1, LUA_MULTRET); 11 | return lua_gettop(L); 12 | } 13 | 14 | static const struct luaL_Reg libproxy[] = { 15 | {"proxycall", proxycall}, 16 | {NULL, NULL} 17 | }; 18 | 19 | LUA_API int luaopen_libproxy(lua_State *L) 20 | { 21 | luaL_register(L, "libproxy", libproxy); 22 | return 1; 23 | } 24 | -------------------------------------------------------------------------------- /test/tarantool-tests/gh-6189-cur_L.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('gh-6189-cur_L'):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | }) 5 | 6 | test:plan(1) 7 | 8 | local libcur_L = require('libcur_L') 9 | 10 | local function cbool(cond) 11 | if cond then 12 | return 1 13 | else 14 | return 0 15 | end 16 | end 17 | 18 | -- Compile function to trace with snapshot. 19 | jit.opt.start('hotloop=1') 20 | -- First call makes `cbool()` hot enough to be recorded next time. 21 | cbool(true) 22 | -- Second call records `cbool()` body (i.e. `if` branch). This is 23 | -- a root trace for `cbool()`. 24 | cbool(true) 25 | 26 | assert(pcall(libcur_L.error_from_other_thread) == false, "return from error") 27 | -- Call with restoration from a snapshot with wrong cur_L. 28 | cbool(false) 29 | 30 | test:ok(true) 31 | test:done(true) 32 | -------------------------------------------------------------------------------- /test/tarantool-tests/gh-6189-cur_L/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) 2 | BuildTestCLib(libcur_L libcur_L.c ${test_name}.test.lua) 3 | -------------------------------------------------------------------------------- /test/tarantool-tests/gh-6189-cur_L/libcur_L.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #undef NDEBUG 5 | #include 6 | 7 | static lua_State *old_L = NULL; 8 | 9 | int throw_error_at_old_thread(lua_State *cur_L) 10 | { 11 | lua_error(old_L); 12 | /* Unreachable. */ 13 | return 0; 14 | } 15 | 16 | static int error_from_other_thread(lua_State *L) 17 | { 18 | lua_State *next_cur_L = lua_newthread(L); 19 | old_L = L; 20 | /* Remove thread. */ 21 | lua_pop(L, 1); 22 | /* Do not show frame slot as return result after error. */ 23 | lua_pushnil(L); 24 | lua_pushcfunction(next_cur_L, throw_error_at_old_thread); 25 | lua_call(next_cur_L, 0, 0); 26 | /* Unreachable. */ 27 | assert(0); 28 | return 0; 29 | } 30 | 31 | static const struct luaL_Reg libcur_L[] = { 32 | {"error_from_other_thread", error_from_other_thread}, 33 | {NULL, NULL} 34 | }; 35 | 36 | LUA_API int luaopen_libcur_L(lua_State *L) 37 | { 38 | luaL_register(L, "libcur_L", libcur_L); 39 | return 1; 40 | } 41 | -------------------------------------------------------------------------------- /test/tarantool-tests/gh-6371-string-char-no-arg.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | -- Test file to demonstrate assertion after `string.char()` 3 | -- recording. 4 | -- See also, https://github.com/tarantool/tarantool/issues/6371. 5 | local test = tap.test('gh-6371-string-char-no-arg'):skipcond({ 6 | ['Test requires JIT enabled'] = not jit.status(), 7 | }) 8 | 9 | -- XXX: Number of loop iterations. 10 | -- * 1 -- instruction becomes hot. 11 | -- * 2 -- recording of the loop body. 12 | -- * 3 -- required for trace finalization, but this iteration 13 | -- runs the generated mcode and reproduces the issue. 14 | local NTEST = 3 15 | test:plan(NTEST) 16 | 17 | -- Storage for the results to avoid trace aborting by `test:ok()`. 18 | -- XXX: Use `table.new()` here to avoid side exit from trace by 19 | -- table resizing. 20 | local results = require('table.new')(3, 0) 21 | jit.opt.start('hotloop=1') 22 | for _ = 1, NTEST do 23 | table.insert(results, string.char()) 24 | end 25 | 26 | for i = 1, NTEST do 27 | test:ok(results[i] == '', 'correct recording of string.char() without args') 28 | end 29 | 30 | test:done(true) 31 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1004-oom-error-frame/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) 2 | BuildTestCLib(testoomframe testoomframe.c ${test_name}.test.lua) 3 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1004-oom-error-frame/testoomframe.c: -------------------------------------------------------------------------------- 1 | #include "lua.h" 2 | #include "lauxlib.h" 3 | 4 | static int allocate_userdata(lua_State *L) 5 | { 6 | lua_newuserdata(L, 1); 7 | return 1; 8 | } 9 | 10 | static const struct luaL_Reg testoomframe[] = { 11 | {"allocate_userdata", allocate_userdata}, 12 | {NULL, NULL} 13 | }; 14 | 15 | LUA_API int luaopen_testoomframe(lua_State *L) 16 | { 17 | luaL_register(L, "testoomframe", testoomframe); 18 | return 1; 19 | } 20 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1033-fix-parsing-predict-next.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('lj-1033-fix-parsing-predict-next') 3 | 4 | test:plan(3) 5 | 6 | -- The resulting bytecode is the following: 7 | -- 8 | -- 0001 KNIL 0 1 9 | -- 0002 MOV 2 1 10 | -- 0003 TGETS 1 1 0 ; "foo" 11 | -- 0004 CALL 1 4 2 12 | -- 13 | -- This MOV doesn't use any variable value from the stack, so the 14 | -- attempt to get the name in `predict_next() leads to the crash. 15 | local res_f = loadstring([[ 16 | -- This local variable is necessary, because it emits `KPRI` 17 | -- bytecode, with which the next `KPRI` bytecode will be merged. 18 | local _ 19 | for _ in (nil):foo() do end 20 | ]]) 21 | 22 | test:ok(res_f, 'chunk loaded successfully') 23 | 24 | local res, err = pcall(res_f) 25 | 26 | -- Check consistency with PUC Rio Lua 5.1 behaviour. 27 | test:ok(not res, 'loaded function not executed') 28 | test:like(err, 'attempt to index a nil value', 'correct error message') 29 | 30 | test:done(true) 31 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1043-asm-fload.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate LuaJIT's misbehaviour during the 4 | -- assembling of the `FLOAD` on MIPS. 5 | -- See also: https://github.com/LuaJIT/LuaJIT/issues/1043. 6 | local test = tap.test('lj-1043-asm-fload'):skipcond({ 7 | ['Test requires JIT enabled'] = not jit.status(), 8 | }) 9 | 10 | test:plan(1) 11 | 12 | local math_abs = math.abs 13 | 14 | local results = {nil, nil, nil, nil} 15 | 16 | -- Disable optimizations to be sure that we assemble `FLOAD`. 17 | jit.opt.start(0, 'hotloop=1') 18 | for i = 1, 4 do 19 | results[i] = math_abs(i - 10) 20 | end 21 | 22 | test:is_deeply(results, {9, 8, 7, 6}, 'correct assembling of the FLOAD') 23 | 24 | test:done(true) 25 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1054-fix-incorrect-pc-value-in-predict-next.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('lj-1054-fix-incorrect-pc-value-in-predict_next') 3 | test:plan(3) 4 | 5 | -- The test demonstrates a problem with out-of-boundary 6 | -- access to a stack. The problem can be easily observed 7 | -- on execution of the sample by LuaJIT instrumented by ASAN, 8 | -- where the sanitizer reports a heap-based buffer overflow. 9 | -- See also https://github.com/LuaJIT/LuaJIT/issues/1054. 10 | 11 | local res_f = loadstring([[ 12 | a, b, c = 1, 2, 3 13 | local d 14 | for _ in nil do end 15 | ]]) 16 | 17 | test:ok(res_f, 'chunk loaded successfully') 18 | 19 | local res, err = pcall(res_f) 20 | 21 | -- Check consistency with PUC Rio Lua 5.1 behaviour. 22 | test:ok(not res, 'loaded function is failed (expected)') 23 | test:like(err, 'attempt to call a nil value', 'correct error message') 24 | 25 | test:done(true) 26 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1066-fix-cur_L-after-coroutine-resume.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('lj-1066-fix-cur_L-after-coroutine-resume'):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | }) 5 | 6 | test:plan(1) 7 | 8 | local libcur_L_coroutine = require('libcur_L_coroutine') 9 | 10 | local function cbool(cond) 11 | if cond then 12 | return 1 13 | else 14 | return 0 15 | end 16 | end 17 | 18 | -- Compile function to trace with snapshot. 19 | jit.opt.start('hotloop=1') 20 | -- First call makes `cbool()` hot enough to be recorded next time. 21 | cbool(true) 22 | -- Second call records `cbool()` body (i.e. `if` branch). This is 23 | -- a root trace for `cbool()`. 24 | cbool(true) 25 | 26 | local res = pcall(libcur_L_coroutine.error_after_coroutine_return) 27 | assert(res == false, 'return from error') 28 | -- Call with restoration from a snapshot with wrong cur_L. 29 | cbool(false) 30 | 31 | test:ok(true) 32 | test:done(true) 33 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1066-fix-cur_L-after-coroutine-resume/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) 2 | BuildTestCLib(libcur_L_coroutine libcur_L_coroutine.c ${test_name}.test.lua) 3 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1066-fix-cur_L-after-coroutine-resume/libcur_L_coroutine.c: -------------------------------------------------------------------------------- 1 | #include "lua.h" 2 | #include "lauxlib.h" 3 | 4 | static int error_after_coroutine_return(lua_State *L) 5 | { 6 | lua_State *innerL = lua_newthread(L); 7 | luaL_loadstring(innerL, "return"); 8 | lua_pcall(innerL, 0, 0, 0); 9 | luaL_error(L, "my fancy error"); 10 | return 0; 11 | } 12 | 13 | static const struct luaL_Reg libcur_L_coroutine[] = { 14 | {"error_after_coroutine_return", error_after_coroutine_return}, 15 | {NULL, NULL} 16 | }; 17 | 18 | LUA_API int luaopen_libcur_L_coroutine(lua_State *L) 19 | { 20 | luaL_register(L, "libcur_L_coroutine", libcur_L_coroutine); 21 | return 1; 22 | } 23 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1117-fuse-across-table-clear.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | -- Test file to demonstrate LuaJIT's incorrect fusion across 3 | -- `table.clear()`. 4 | -- See also: https://github.com/LuaJIT/LuaJIT/issues/1117. 5 | local test = tap.test('lj-1117-fuse-across-table-clear'):skipcond({ 6 | ['Test requires JIT enabled'] = not jit.status(), 7 | }) 8 | 9 | local ffi = require('ffi') 10 | local table_clear = require('table.clear') 11 | 12 | test:plan(1) 13 | 14 | local tab = {0} 15 | local alias_tab = tab 16 | local result_tab = {} 17 | 18 | jit.opt.start('hotloop=1') 19 | 20 | for i = 1, 4 do 21 | -- Load to be fused. 22 | local value = tab[1] 23 | -- Clear the alias table to trick the code flow analysis. 24 | table_clear(alias_tab) 25 | -- Need this cast to trigger load fusion. See `asm_comp()` for 26 | -- the details. Before the patch, this fusion takes the 27 | -- incorrect address of the already cleared table, which leads 28 | -- to the failure of the check below. 29 | result_tab[i] = ffi.cast('int64_t', value) 30 | -- Revive the value. 31 | tab[1] = 0 32 | end 33 | 34 | test:samevalues(result_tab, 'no fusion across table.clear') 35 | 36 | test:done(true) 37 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1134-hotside-jit-off.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate the JIT misbehaviour, when the side 4 | -- trace is compiled after `jit.off()`. 5 | -- See also: https://github.com/LuaJIT/LuaJIT/issues/1134. 6 | 7 | local test = tap.test('lj-1134-hotside-jit-off'):skipcond({ 8 | ['Test requires JIT enabled'] = not jit.status(), 9 | ['Disabled on *BSD due to #4819'] = jit.os == 'BSD', 10 | }) 11 | 12 | -- `traceinfo()` takes the trace number as an argument. 13 | local traceinfo = require('jit.util').traceinfo 14 | 15 | test:plan(1) 16 | 17 | local take_side 18 | local function trace() 19 | -- luacheck: ignore 20 | -- Branch for the side exit. 21 | if take_side then end 22 | end 23 | 24 | -- Flush all possible traces. 25 | jit.flush() 26 | 27 | jit.opt.start('hotloop=1', 'hotexit=1') 28 | 29 | trace() 30 | trace() 31 | 32 | assert(traceinfo(1), 'root trace not compiled') 33 | 34 | -- Force trace exit. 35 | take_side = true 36 | 37 | jit.off() 38 | 39 | -- Attempt to compile a side trace. 40 | trace() 41 | trace() 42 | 43 | test:ok(not traceinfo(2), 'no side trace compiled') 44 | 45 | test:done(true) 46 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1149-g-number-formating-bufov.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate stack-buffer-overflow in the 4 | -- `lj_strfmt_wfnum()` call. 5 | -- See also: https://github.com/LuaJIT/LuaJIT/issues/1149. 6 | 7 | local test = tap.test('lj-1149-g-number-formating-bufov') 8 | test:plan(1) 9 | 10 | -- XXX: The test shows stack-buffer-overflow only under ASAN. 11 | -- The number value for the test has the same precision 12 | -- (`prec` = 5) and amount of digits (`hilen` = 5) for the decimal 13 | -- representation. Hence, with `ndhi` == 0, the `ndlo` part 14 | -- becomes 64 (the size of the `nd` stack buffer), and the 15 | -- overflow occurs. 16 | -- See details in the :`lj_strfmt_wfnum()`. 17 | test:is(string.format('%7g', 0x1.144399609d407p+401), '5.5733e+120', 18 | 'correct format %7g result') 19 | 20 | test:done(true) 21 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1168-unmarked-finalizer-tab.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- This test demonstrates LuaJIT's heap-use-after-free on 4 | -- cleaning of resources during shutdown. The test simulates 5 | -- "unloading" of the library, or removing some of its 6 | -- functionality and then calls `collectgarbage`. 7 | -- See https://github.com/LuaJIT/LuaJIT/issues/1168 for details. 8 | local test = tap.test('lj-1168-unmarked-finalizer-tab') 9 | test:plan(1) 10 | 11 | local ffi = require('ffi') 12 | 13 | ffi.gc = nil 14 | collectgarbage() 15 | 16 | test:ok(true, 'no heap use after free') 17 | 18 | test:done(true) 19 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1172-debug-handling-ref.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate the heap-use-after-free, error for 4 | -- `debug.setmetatable()` and enabled `jit.dump()`. 5 | -- The test fails under ASAN. 6 | -- See also: https://github.com/LuaJIT/LuaJIT/issues/1172. 7 | 8 | local test = tap.test('lj-1172-debug-handling-ref'):skipcond({ 9 | ['Test requires JIT enabled'] = not jit.status(), 10 | }) 11 | 12 | local jdump = require('jit.dump') 13 | 14 | test:plan(1) 15 | 16 | -- We need to trigger the `TRACE` vmevent handler during 17 | -- `debug.setmetatable()`. It will cause Lua stack reallocation. 18 | jdump.start('t', '/dev/null') 19 | 20 | -- Use `coroutine.wrap()` to create a new Lua stack with a minimum 21 | -- number of stack slots. 22 | coroutine.wrap(function() 23 | -- "TRACE flush" event handler causes stack reallocation and 24 | -- leads to heap-use-after-free. This event handler is called 25 | -- because all traces are specialized to base metatables, so 26 | -- if we update any base metatable, we must flush all traces. 27 | debug.setmetatable(1, {}) 28 | end)() 29 | 30 | test:ok(true, 'no heap-use-after-free error') 31 | 32 | test:done(true) 33 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1193-out-of-bounds-snap-restoredata.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate LuaJIT's out-of-bounds access during 4 | -- the saving of registers content in `snap_restoredata()`. 5 | -- See also: https://github.com/LuaJIT/LuaJIT/issues/1193. 6 | 7 | local test = tap.test('lj-1193-out-of-bounds-snap-restoredata'):skipcond({ 8 | ['Test requires JIT enabled'] = not jit.status(), 9 | }) 10 | 11 | local ffi = require('ffi') 12 | 13 | test:plan(1) 14 | 15 | local double_type = ffi.typeof('double') 16 | 17 | jit.opt.start('hotloop=1') 18 | local x = 1LL 19 | for _ = 1, 4 do 20 | -- `x` is saved in the fpr register and will be restored in the 21 | -- `ex->fpr` during exit from the snapshot. But out-of-bounds 22 | -- access is happening due to indexing `ex->gpr` occasionally. 23 | x = double_type(x + 1) 24 | end 25 | 26 | test:ok(true, 'no out-of-bounds failure') 27 | 28 | test:done(true) 29 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1203-limit-format-elements.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate LuaJIT incorrect recording of 4 | -- `string.format()` function with huge amount of elements. 5 | -- See also: https://github.com/LuaJIT/LuaJIT/issues/1203. 6 | 7 | local test = tap.test('lj-1203-limit-format-elements'):skipcond({ 8 | ['Test requires JIT enabled'] = not jit.status(), 9 | }) 10 | 11 | test:plan(1) 12 | 13 | jit.opt.start('hotloop=1') 14 | 15 | -- XXX: Use a huge amount of format elements to process, which 16 | -- creates a lot of string constants. 17 | local NELEMENTS = 25000 18 | local fmt = ('%'):rep(NELEMENTS * 2) 19 | local expected = ('%'):rep(NELEMENTS) 20 | local result 21 | for _ = 1, 4 do 22 | result = fmt:format() 23 | end 24 | 25 | test:is(result, expected, 'no IR buffer underflow and the correct result') 26 | 27 | test:done(true) 28 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1224-fix-cdata-arith-side.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate LuaJIT's incorrect recording for the 4 | -- side trace with cdata arithmetic, which raises the error. 5 | -- See also: https://github.com/LuaJIT/LuaJIT/issues/1224. 6 | 7 | local test = tap.test('lj-1224-fix-cdata-arith-side'):skipcond({ 8 | ['Test requires JIT enabled'] = not jit.status(), 9 | }) 10 | 11 | -- The loading of the 'tap' module initializes `cts->L` during 12 | -- parsing. Run standalone script for testing. 13 | local script = require('utils').exec.makecmd(arg) 14 | 15 | test:plan(1) 16 | 17 | local output = script() 18 | test:is(output, 'OK', 'correct recording with uninitialized cts->L') 19 | 20 | test:done(true) 21 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1224-fix-cdata-arith-side/script.lua: -------------------------------------------------------------------------------- 1 | local function test_record_protected() 2 | -- Start the root trace here. 3 | for _ = 1, 3 do end 4 | -- An exit from the root trace triggered the side trace 5 | -- recording. 6 | local _ = 1LL + '' 7 | end 8 | 9 | jit.opt.start('hotloop=1', 'hotexit=1') 10 | 11 | local status, errmsg = pcall(test_record_protected) 12 | 13 | assert(not status, 'recoding correctly handling the error') 14 | assert(errmsg:match('attempt to perform arithmetic'), 'correct error message') 15 | 16 | print('OK') 17 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1224-fix-cdata-arith.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate LuaJIT's incorrect recording of cdata 4 | -- arithmetic, which raises the error. 5 | -- See also: https://github.com/LuaJIT/LuaJIT/issues/1224. 6 | 7 | local test = tap.test('lj-1224-fix-cdata-arith'):skipcond({ 8 | ['Test requires JIT enabled'] = not jit.status(), 9 | }) 10 | 11 | -- The loading of the 'tap' module initializes `cts->L` during 12 | -- parsing. Run standalone script for testing. 13 | local script = require('utils').exec.makecmd(arg) 14 | 15 | test:plan(1) 16 | 17 | local output = script() 18 | test:is(output, 'OK', 'correct recording with uninitialized cts->L') 19 | 20 | test:done(true) 21 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1224-fix-cdata-arith/script.lua: -------------------------------------------------------------------------------- 1 | local function test_record_protected() 2 | local i = 1 3 | while i < 3 do 4 | -- Use `while` to start compilation of the trace at the first 5 | -- iteration, before `cts->L` is uninitialized. 6 | local _ = 1LL + nil 7 | i = i + 1 8 | end 9 | end 10 | 11 | jit.opt.start('hotloop=1') 12 | 13 | local status, errmsg = pcall(test_record_protected) 14 | 15 | assert(not status, 'recoding correctly handling the error') 16 | assert(errmsg:match('attempt to perform arithmetic'), 'correct error message') 17 | 18 | print('OK') 19 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1226-fix-predict-next.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('lj-1226-fix-predict-next') 3 | 4 | test:plan(3) 5 | 6 | -- The resulting bytecode is the following: 7 | -- 8 | -- 0001 KNIL 0 3 9 | -- 0002 JMP 4 => 0003 10 | -- 0003 => ITERC 4 2 3 11 | -- 0004 ITERL 4 => 0003 12 | -- 13 | -- The parsing of the `for` iterator uses the incorrect check for 14 | -- `fs->bclim`, which allows the usage of an uninitialized value, 15 | -- so the test fails under Valgrind. 16 | local res_f = loadstring([[ 17 | -- This local variable is necessary, because it emits `KPRI` 18 | -- bytecode, with which the next `KPRI` bytecode will be merged. 19 | local _ 20 | for _ in nil do end 21 | ]]) 22 | 23 | test:ok(res_f, 'chunk loaded successfully') 24 | 25 | local res, err = pcall(res_f) 26 | 27 | -- Check consistency with PUC Rio Lua 5.1 behaviour. 28 | test:ok(not res, 'loaded function not executed') 29 | test:like(err, 'attempt to call a nil value', 'correct error message') 30 | 31 | test:done(true) 32 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1232-fix-enum-tostring.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate heap-buffer-overflow in the 4 | -- `tostring()` call for the enum cdata. 5 | -- See also: https://github.com/LuaJIT/LuaJIT/issues/1232. 6 | 7 | local test = tap.test('lj-1232-fix-enum-tostring') 8 | 9 | local ffi = require('ffi') 10 | local ENUM_VAL = 1 11 | local EXPECTED = 'cdata: ' .. ENUM_VAL 12 | 13 | test:plan(1) 14 | 15 | local cdata_enum = ffi.new(('enum {foo = %d}'):format(ENUM_VAL), ENUM_VAL) 16 | 17 | -- XXX: The test shows heap-buffer-overflow only under ASAN. 18 | 19 | test:like(tostring(cdata_enum), EXPECTED, 'correct tostring result') 20 | 21 | test:done(true) 22 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1252-missing-bit64-coercion.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate LuaJIT incorrect recording of 4 | -- `bit` library with needed coercion from string. 5 | -- See also: https://github.com/LuaJIT/LuaJIT/issues/1252. 6 | 7 | local test = tap.test('lj-1252-missing-bit64-coercion'):skipcond({ 8 | ['Test requires JIT enabled'] = not jit.status(), 9 | }) 10 | 11 | test:plan(1) 12 | 13 | -- Simplify the `jit.dump()` output. 14 | local bor = bit.bor 15 | 16 | jit.opt.start('hotloop=1') 17 | 18 | -- Before the patch, with the missed coercion from string, there 19 | -- is the cast to `i64` from `p64`, where the last one is the 20 | -- string address. This leads to an incorrect result of the bit 21 | -- operation. 22 | 23 | local results = {} 24 | for i = 1, 4 do 25 | results[i] = bor('0', 0LL) 26 | end 27 | 28 | test:samevalues(results, 'correct recording of the bit operation with coercion') 29 | 30 | test:done(true) 31 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1273-dualnum-bit-coercion.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate LuaJIT misbehaviour on operating 4 | -- for 64-bit operands in built-in `bit` library in DUALNUM mode. 5 | -- See also, https://github.com/LuaJIT/LuaJIT/issues/1273. 6 | 7 | local test = tap.test('lj-1273-dualnum-bit-coercion') 8 | test:plan(1) 9 | 10 | local bit = require('bit') 11 | 12 | -- The cdata value for 2 ^ 33. 13 | local EXPECTED = 2 ^ 33 + 0LL 14 | -- Same value is used as mask for `bit.band()`. 15 | local MASK = EXPECTED 16 | 17 | test:is(bit.band(2 ^ 33, MASK), EXPECTED, 'correct bit.band result') 18 | 19 | test:done(true) 20 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1329-getfenv-setfenv-negative.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- The test file to demonstrate UBSan warning for `setfenv()` and 4 | -- `getfenv()` with a huge `level` value. 5 | -- See also: https://github.com/LuaJIT/LuaJIT/issues/1329. 6 | local test = tap.test('lj-1329-getfenv-setfenv-negative') 7 | 8 | test:plan(4) 9 | 10 | -- This number will be equal to `INT_MIN` when casted to `int`. 11 | -- After this, it will be decremented in `lj_debug_level()` and 12 | -- underflowed to the `INT_MAX`. That produces the UBSan warning 13 | -- about signed integer overflow. 14 | local LEVEL = 2 ^ 31 15 | local ERRMSG = 'invalid level' 16 | 17 | -- Tests check the UBSan runtime error. Add assertions just to be 18 | -- sure that we don't change the behaviour. 19 | local status, errmsg = pcall(getfenv, LEVEL) 20 | test:ok(not status, 'getfenv: correct status') 21 | test:like(errmsg, ERRMSG, 'getfenv: correct error message') 22 | 23 | status, errmsg = pcall(setfenv, LEVEL, {}) 24 | test:ok(not status, 'setfenv: correct status') 25 | test:like(errmsg, ERRMSG, 'setfenv: correct error message') 26 | 27 | test:done(true) 28 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-1345-flushing-trace-twice.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate incorrect behaviour when LuaJIT 4 | -- flushes the trace twice when another trace for the same 5 | -- starting bytecode was recorded. 6 | -- See also https://github.com/LuaJIT/LuaJIT/issues/1345. 7 | local test = tap.test('lj-1345-flushing-trace-twice'):skipcond({ 8 | ['Test requires JIT enabled'] = not jit.status(), 9 | }) 10 | 11 | test:plan(1) 12 | 13 | -- Reset JIT. 14 | jit.flush() 15 | collectgarbage() 16 | 17 | jit.opt.start('hotloop=1') 18 | 19 | for _ = 1, 3 do 20 | -- Nothing to flush on the first iteration. On the second 21 | -- iteration, flushing the trace for the loop below (from the 22 | -- first iteration). On the third iteration, another trace (from 23 | -- the second iteration) is recorded for that loop. 24 | -- This leads to the assertion failure before this patch. 25 | jit.flush(1) 26 | -- Record the loop with a trace. 27 | for _ = 1, 4 do end 28 | end 29 | 30 | test:ok(true, 'no assertion failure during trace flushing') 31 | test:done(true) 32 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-351-print-tostring-number.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | local test = tap.test('lj-351-print-tostring-number') 4 | test:plan(8) 5 | 6 | local script = require('utils').exec.makecmd(arg) 7 | 8 | local cases = { 9 | {typename = 'nil', value = 'nil'}, 10 | {typename = 'boolean', value = 'true'}, 11 | {typename = 'number', value = '42'}, 12 | -- FIXME: Test case below is disabled, because __tostring 13 | -- metamethod isn't checked for string base metatable. 14 | -- See also https://github.com/tarantool/tarantool/issues/6746. 15 | -- {typename = 'string', value = '[[teststr]]'}, 16 | {typename = 'table', value = '{}'}, 17 | {typename = 'function', value = 'function() end'}, 18 | {typename = 'userdata', value = 'newproxy()'}, 19 | {typename = 'thread', value = 'coroutine.create(function() end)'}, 20 | {typename = 'cdata', value = '1ULL'} 21 | } 22 | 23 | for _, subtest in pairs(cases) do 24 | local output = script(('"%s"'):format(subtest.value), subtest.typename) 25 | test:is(output, ('__tostring is reloaded for %s'):format(subtest.typename), 26 | ('subtest is OK for %s type'):format(subtest.typename)) 27 | end 28 | 29 | test:done(true) 30 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-351-print-tostring-number/script.lua: -------------------------------------------------------------------------------- 1 | local test = [[ 2 | local testvar = %s 3 | debug.setmetatable(testvar, {__tostring = function(o) 4 | return ('__tostring is reloaded for %s'):format(type(o)) 5 | end}) 6 | print(testvar) 7 | ]] 8 | 9 | pcall(load(test:format(unpack(arg)))) 10 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-357-arm64-hrefk.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | -- Test file to demonstrate the incorrect JIT behaviour for HREFK 3 | -- IR compilation on arm64. 4 | -- See also https://github.com/LuaJIT/LuaJIT/issues/357. 5 | local test = tap.test('lj-357-arm64-hrefk'):skipcond({ 6 | ['Test requires JIT enabled'] = not jit.status(), 7 | }) 8 | 9 | test:plan(2) 10 | 11 | jit.opt.start('hotloop=1', 'hotexit=1') 12 | 13 | local t = {hrefk = 0} 14 | 15 | -- XXX: Need to generate a bunch of side traces (starts a new one 16 | -- when the hmask is changed) to wait, when the register allocator 17 | -- chooses the same register as a base register for offset and 18 | -- destination in LDR instruction. 19 | -- We need 1028 iterations = 1024 iteration for 10 table rehashing 20 | -- (create side traces for invariant and variant loop part) + 21 | -- 3 for trace initialize + 1 to run the bad trace. 22 | local START = 1028 23 | local STOP = 1 24 | for i = START, STOP, -1 do 25 | t.hrefk = t.hrefk - 1 26 | t[t.hrefk] = i 27 | end 28 | 29 | test:is(t.hrefk, -START) 30 | test:is(t[t.hrefk], STOP) 31 | 32 | test:done(true) 33 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-378-string-format-c-null-char.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | local test = tap.test('lj-378-string-format-c-null-char') 4 | test:plan(1) 5 | 6 | -- Test file to check that there is no regression in 7 | -- `string.format('%c', 0)` behaviour. 8 | -- See also https://github.com/LuaJIT/LuaJIT/issues/378. 9 | 10 | test:is(string.format('%c', 0), '\0', 'string.format %c on null char') 11 | test:done(true) 12 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-416-xor-before-jcc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) 2 | BuildTestCLib(libtestxor testxor.c ${test_name}.test.lua) 3 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-416-xor-before-jcc/testxor.c: -------------------------------------------------------------------------------- 1 | #define UNUSED(x) ((void)x) 2 | 3 | int test_xor_func(int a, int b, int c, int d, int e, int f, void *g, int h) 4 | { 5 | UNUSED(a); 6 | UNUSED(b); 7 | UNUSED(c); 8 | UNUSED(d); 9 | UNUSED(e); 10 | UNUSED(f); 11 | UNUSED(g); 12 | UNUSED(h); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-418-assert-any-type.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- See also https://github.com/LuaJIT/LuaJIT/issues/418. 4 | local test = tap.test('lj-418-asset-any-type') 5 | test:plan(2) 6 | 7 | local retv = {} 8 | 9 | local st, err = pcall(assert, false, retv) 10 | assert(not st, 'pcall fails') 11 | 12 | test:ok(err == retv, 'assert function take non-string argument') 13 | 14 | xpcall(assert, function(obj) 15 | test:ok(obj == retv, 'xpcall error handler function get non-string argument') 16 | end, false, retv) 17 | 18 | test:done(true) 19 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-463-os-date-oom.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- See also https://github.com/LuaJIT/LuaJIT/issues/463. 4 | local test = tap.test('lj-463-os-date-oom') 5 | test:plan(1) 6 | 7 | -- Try all available locales to check the behaviour. 8 | -- Before the patch, the call to `os.date('%p')` on non-standard 9 | -- locale (ru_RU.utf8, sv_SE.utf8, etc.) may lead to OOM. 10 | for locale in io.popen('locale -a'):read('*a'):gmatch('([^\n]*)\n?') do 11 | os.setlocale(locale) 12 | os.date('%p') 13 | end 14 | 15 | test:ok(true, 'os.date() finished without OOM') 16 | 17 | test:done(true) 18 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-505-fold-no-strref-for-ptrdiff.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test("lj-505-fold-icorrect-behavior"):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | }) 5 | 6 | test:plan(1) 7 | 8 | -- Test file to demonstrate Lua fold machinery icorrect behavior, 9 | -- details: 10 | -- https://github.com/LuaJIT/LuaJIT/issues/505 11 | 12 | jit.opt.start("hotloop=1") 13 | for _ = 1, 20 do 14 | local value = "abc" 15 | local pos_c = string.find(value, "c", 1, true) 16 | local value2 = string.sub(value, 1, pos_c - 1) 17 | local pos_b = string.find(value2, "b", 2, true) 18 | assert(pos_b == 2, "FAIL: position of 'b' is " .. pos_b) 19 | end 20 | test:ok(true, "string.find offset aritmetics wasn't broken while recording") 21 | 22 | test:done(true) 23 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-509-debug-getinfo-arguments-check.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate crash in the `debug.getinfo()` call. 4 | -- See also: https://github.com/LuaJIT/LuaJIT/issues/509. 5 | local test = tap.test('lj-509-debug-getinfo-arguments-check.test.lua') 6 | test:plan(2) 7 | 8 | -- '>' expects to have an extra argument on the stack. 9 | local res, err = pcall(debug.getinfo, 1, '>S') 10 | test:ok(not res, 'check result of the call with invalid arguments') 11 | test:like(err, 'bad argument', 'check the error message') 12 | 13 | test:done(true) 14 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-512-profiler-hook-finalizers.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local profile = require('jit.profile') 3 | 4 | local test = tap.test('lj-512-profiler-hook-finalizers'):skipcond({ 5 | -- Disable the test since it is time-sensitive. 6 | ['Disabled with Valgrind'] = os.getenv('LUAJIT_TEST_USE_VALGRIND'), 7 | }) 8 | test:plan(1) 9 | 10 | -- Sampling interval in ms. 11 | local INTERVAL = 10 12 | 13 | local nsamples = 0 14 | profile.start('li'..tostring(INTERVAL), function() 15 | nsamples = nsamples + 1 16 | end) 17 | 18 | local start = os.clock() 19 | for _ = 1, 1e6 do 20 | getmetatable(newproxy(true)).__gc = function() end 21 | end 22 | local finish = os.clock() 23 | 24 | profile.stop() 25 | 26 | -- XXX: The bug is occurred as stopping of callbacks invocation, 27 | -- when a new tick strikes inside `gc_call_finalizer()`. 28 | -- The amount of successful callbacks isn't stable (2-15). 29 | -- So, assume that amount of profiling samples should be at least 30 | -- more than 0.5 intervals of time during sampling. 31 | test:ok(nsamples >= 0.5 * (finish - start) * 1e3 / INTERVAL, 32 | 'profiler sampling') 33 | 34 | test:done(true) 35 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-522-fix-dlerror-return-null.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('lj-522-fix-dlerror-return-null'):skipcond({ 3 | -- XXX: Unfortunately, it's too hard to overload (or even 4 | -- impossible, who knows, since Cupertino fellows do not 5 | -- provide any information about their system) something from 6 | -- dyld sharing cache (includes the library 7 | -- providing `dlerror()`). 8 | -- All in all, this test checks the part that is common for all 9 | -- platforms, so it's not vital to run this test on macOS since 10 | -- everything can be checked on Linux in a much easier way. 11 | [' cannot be overridden on macOS'] = jit.os == 'OSX', 12 | }) 13 | 14 | test:plan(1) 15 | 16 | -- `makecmd()` runs <%testname%/script.lua> by 17 | -- `LUAJIT_TEST_BINARY` with the given environment and launch 18 | -- options. 19 | local script = require('utils').exec.makecmd(arg, { 20 | env = { LD_PRELOAD = 'mydlerror.so' }, 21 | redirect = '2>&1', 22 | }) 23 | 24 | local output = script() 25 | test:like(output, 'dlopen failed', 'correct error message') 26 | 27 | test:done(true) 28 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-522-fix-dlerror-return-null/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) 2 | BuildTestCLib(mydlerror mydlerror.c ${test_name}.test.lua) 3 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-522-fix-dlerror-return-null/mydlerror.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char *dlerror(void) 4 | { 5 | return NULL; 6 | } 7 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-522-fix-dlerror-return-null/script.lua: -------------------------------------------------------------------------------- 1 | local ffi = require('ffi') 2 | 3 | -- Overloaded `dlerror()` returns NULL after trying to load an 4 | -- unexisting file. 5 | local res, errmsg = pcall(ffi.load, 'lj-522-fix-dlerror-return-null-unexisted') 6 | 7 | assert(not res, 'pcall should fail') 8 | 9 | -- Return the error message to be checked by the TAP. 10 | io.write(errmsg) 11 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-524-fold-conv-respect-src-irt.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('or-524-fold-icorrect-behavior'):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | }) 5 | 6 | test:plan(1) 7 | 8 | local ffi = require('ffi') 9 | -- Test file to demonstrate LuaJIT folding machinery incorrect 10 | -- behaviour, details: 11 | -- https://github.com/LuaJIT/LuaJIT/issues/524 12 | -- https://github.com/moonjit/moonjit/issues/37 13 | 14 | jit.opt.start(0, "fold", "cse", "fwd", "hotloop=1") 15 | 16 | local sq = ffi.cast("uint32_t", 42) 17 | 18 | for _ = 1, 3 do 19 | sq = ffi.cast("uint32_t", sq * sq) 20 | end 21 | 22 | test:is(tonumber(sq), math.fmod(math.pow(42, 8), math.pow(2, 32))) 23 | 24 | test:done(true) 25 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-528-tonumber-0.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate LuaJIT `tonumber('-0')` incorrect 4 | -- behaviour. 5 | -- See also https://github.com/LuaJIT/LuaJIT/issues/528, 6 | -- https://github.com/LuaJIT/LuaJIT/pull/787. 7 | local test = tap.test('lj-528-tonumber-0') 8 | test:plan(1) 9 | 10 | -- As numbers -0 equals to 0, so convert it back to string. 11 | test:ok(tostring(tonumber('-0')) == '-0', 'correct "-0" string parsing') 12 | 13 | test:done(true) 14 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-549-bytecode-loader/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LIB_NAME "script") 2 | set(LUA_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.lua) 3 | set(C_FILE ${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}.c) 4 | 5 | make_lua_path(LUA_PATH 6 | PATHS 7 | ${LUAJIT_SOURCE_DIR}/?.lua 8 | ${LUAJIT_SOURCE_DIR}/jit/?.lua 9 | ) 10 | 11 | add_custom_target(export_bc 12 | COMMAND ${CMAKE_COMMAND} -E env 13 | LUA_PATH=${LUA_PATH} ${LUAJIT_TEST_BINARY} -b ${LUA_FILE} ${C_FILE} 14 | DEPENDS ${LUAJIT_TEST_BINARY} ${LUA_FILE} 15 | BYPRODUCTS ${C_FILE} 16 | COMMENT "Exporting bytecode to a C file" 17 | VERBATIM 18 | ) 19 | 20 | get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) 21 | BuildTestCLib(${LIB_NAME} ${C_FILE} ${test_name}.test.lua) 22 | add_dependencies(${LIB_NAME} export_bc) 23 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-549-bytecode-loader/script.lua: -------------------------------------------------------------------------------- 1 | return { 2 | msg = 'Lango team', 3 | } 4 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-551-bytecode-c-broken-macro.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('lj-551-bytecode-c-broken-macro'):skipcond({ 3 | -- XXX: Tarantool doesn't use default LuaJIT loaders, and Lua 4 | -- bytecode can't be loaded from the shared library. For more 5 | -- info: https://github.com/tarantool/tarantool/issues/9671. 6 | ['Test uses exotic type of loaders (see #9671)'] = _TARANTOOL, 7 | }) 8 | 9 | test:plan(4) 10 | 11 | local function check_module(t, module_name) 12 | local ok, module = pcall(require, module_name) 13 | local message = ('symbol %q is available in a library'):format(module_name) 14 | t:ok(ok, message) 15 | t:is(module.msg, 'Lango team') 16 | end 17 | 18 | check_module(test, 'script_c') 19 | check_module(test, 'script_cc') 20 | 21 | test:done(true) 22 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-551-bytecode-c-broken-macro/script.lua: -------------------------------------------------------------------------------- 1 | return { 2 | msg = 'Lango team', 3 | } 4 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-556-fix-loop-realignment.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('lj-556-fix-loop-realignment'):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | }) 5 | 6 | test:plan(1) 7 | 8 | -- Test file to demonstrate JIT misbehaviour for loop realignment 9 | -- in LUAJIT_NUMMODE=2. See also 10 | -- https://github.com/LuaJIT/LuaJIT/issues/556. 11 | 12 | jit.opt.start('hotloop=1') 13 | 14 | local s = 4 15 | while s > 0 do 16 | s = s - 1 17 | end 18 | 19 | test:ok(true, 'loop is compiled and ran successfully') 20 | test:done(true) 21 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-574-overflow-unpack.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate integer overflow in the `unpack()` 4 | -- function due to compiler optimization. 5 | -- See also https://github.com/LuaJIT/LuaJIT/pull/574. 6 | local test = tap.test('lj-574-overflow-unpack') 7 | test:plan(1) 8 | 9 | local r, e = pcall(unpack, {}, 0, 2^31 - 1) 10 | test:ok(not r and e == 'too many results to unpack', 'overflow check in unpack') 11 | 12 | test:done(true) 13 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-601-fix-gc-finderrfunc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) 2 | BuildTestCLib(libmixcframe mixcframe.c ${test_name}.test.lua) 3 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-671-arm64-assert-after-mremap.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate assertion after `mremap()` on arm64. 4 | -- See also, https://github.com/LuaJIT/LuaJIT/issues/671. 5 | 6 | local test = tap.test('lj-671-arm64-assert-after-mremap') 7 | test:plan(1) 8 | 9 | -- `mremap()` is used on Linux to remap directly mapped big 10 | -- (>=DEFAULT_MMAP_THRESHOLD) memory chunks. 11 | -- The simplest way to test memory move is to allocate the huge 12 | -- memory chunk for string buffer directly and reallocate it 13 | -- after. 14 | -- To allocate a memory buffer with the size up to the threshold 15 | -- for direct mapping `string.rep()` is used with the length that 16 | -- equals to DEFAULT_MMAP_THRESHOLD. 17 | -- Then concatenate the directly mapped result string with the 18 | -- other one to trigger buffer reallocation and its remapping. 19 | 20 | local DEFAULT_MMAP_THRESHOLD = 128 * 1024 21 | local s = string.rep('x', DEFAULT_MMAP_THRESHOLD)..'x' 22 | test:ok(s) 23 | 24 | test:done(true) 25 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-672-cdata-allocation-recording.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('lj-672-cdata-allocation-recording'):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | ['Disabled on *BSD due to #4819'] = jit.os == 'BSD', 5 | }) 6 | 7 | test:plan(1) 8 | 9 | local ffi = require('ffi') 10 | local traceinfo = require('jit.util').traceinfo 11 | 12 | -- Structure with array. 13 | ffi.cdef('struct my_struct {int a; char d[8];}') 14 | 15 | -- Be sure that we have no other traces. 16 | jit.off() 17 | jit.flush() 18 | jit.on() 19 | 20 | jit.opt.start("hotloop=1") 21 | -- Hoist variable declaration to avoid allocation sinking for the 22 | -- trace below. 23 | local r 24 | for i = 1, 3 do 25 | r = ffi.new('struct my_struct') 26 | r.a = i 27 | end 28 | 29 | test:ok(traceinfo(1), 'new trace created') 30 | 31 | test:done(true) 32 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-695-ffi-vararg-call.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | local test = tap.test('lj-695-ffi-vararg-call') 4 | test:plan(2) 5 | 6 | local ffi = require('ffi') 7 | local str = ffi.new('char[256]') 8 | ffi.cdef('int sprintf(char *str, const char *format, ...)') 9 | local strlen = ffi.C.sprintf(str, 'try vararg function: %s:%.2f(%d) - %llu', 10 | 'imun', 9, 9LL, -1ULL) 11 | 12 | local result = ffi.string(str) 13 | test:is(#result, strlen) 14 | test:is(result, 'try vararg function: imun:9.00(9) - 18446744073709551615') 15 | 16 | test:done(true) 17 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-698-arm-pcall-panic.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- See also https://github.com/LuaJIT/LuaJIT/issues/698. 4 | local test = tap.test('lj-418-arm-pcall-panic') 5 | test:plan(1) 6 | 7 | local ffi = require('ffi') 8 | -- The test case below was taken from the LuaJIT-tests 9 | -- suite (lib/ffi/ffi_callback.lua), and should be removed 10 | -- after the integration of the mentioned suite. 11 | local runner = ffi.cast("int (*)(int, int, int, int, int, int, int, int, int)", 12 | function() error("test") end 13 | ) 14 | 15 | local st = pcall(runner, 1, 1, 1, 1, 1, 1, 1, 1, 1) 16 | test:ok(not st, 'error handling completed correctly') 17 | 18 | test:done(true) 19 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-726-profile-flush-close.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | local test = tap.test('lj-726-profile-flush-close'):skipcond({ 4 | -- See also https://github.com/tarantool/tarantool/issues/10803. 5 | ['Disabled due to #10803'] = os.getenv('LUAJIT_TEST_USE_VALGRIND'), 6 | }) 7 | test:plan(1) 8 | 9 | local TEST_FILE = 'lj-726-profile-flush-close.profile' 10 | 11 | local function payload() 12 | local r = 0 13 | for i = 1, 1e8 do 14 | r = r + i 15 | end 16 | return r 17 | end 18 | 19 | local p = require('jit.p') 20 | p.start('f', TEST_FILE) 21 | payload() 22 | p.stop() 23 | 24 | local f, err = io.open(TEST_FILE) 25 | assert(f, err) 26 | 27 | -- Check that file is not empty. 28 | test:ok(f:read(0), 'profile output was flushed and closed') 29 | 30 | assert(os.remove(TEST_FILE)) 31 | 32 | test:done(true) 33 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-727-lightuserdata-itern/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) 2 | BuildTestCLib(lightuserdata lightuserdata.c ${test_name}.test.lua) 3 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-735-io-close-on-closed-file.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | local test = tap.test('lj-735-io-close-on-closed-file') 4 | test:plan(2) 5 | 6 | local TEST_FILE = 'lj-735-io-close-on-closed-file.tmp' 7 | 8 | -- Save the old stdout for the TAP output. 9 | local oldstdout = io.output() 10 | io.output(TEST_FILE) 11 | 12 | local status, err = io.close() 13 | assert(status, err) 14 | 15 | status, err = pcall(io.close) 16 | 17 | io.output(oldstdout) 18 | 19 | test:ok(not status, 'close already closed file') 20 | test:ok(err:match('attempt to use a closed file'), 'correct error message') 21 | 22 | assert(os.remove(TEST_FILE)) 23 | 24 | test:done(true) 25 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-745-ffi-typeinfo-dead-names.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local ffi = require('ffi') 3 | local test = tap.test('lj-745-ffi-typeinfo-dead-names') 4 | 5 | test:plan(1) 6 | 7 | -- Start from the beginning of the GC cycle. 8 | collectgarbage() 9 | 10 | local function ctypes_iteration() 11 | local i = 1 12 | -- Test `checklivetv()` assertion in `setstrV()` inside 13 | -- `ffi.typeinfo()`. 14 | while ffi.typeinfo(i) do i = i + 1 end 15 | end 16 | 17 | -- Call `ffi.typeinfo()` much enough to be sure that strings with 18 | -- names of types become dead. The number of iterations is big 19 | -- enough (more than x2 of the required value) to see assertion 20 | -- failure guaranteed under Tarantool too (it has much more alive 21 | -- objects on start). 22 | for _ = 1, 100 do 23 | ctypes_iteration() 24 | end 25 | 26 | test:ok(true, 'no assertion failure inside ffi.typeinfo()') 27 | 28 | test:done(true) 29 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-762-pcall-no-arg.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to check error raising for `pcall()` without 4 | -- arguments. Regardless that the problem is aarch64-specific, 5 | -- it is good to test it for all arches. 6 | -- See also https://github.com/LuaJIT/LuaJIT/issues/762. 7 | local test = tap.test('lj-762-pcall-no-arg') 8 | test:plan(2) 9 | 10 | local result, err = pcall(pcall) 11 | 12 | test:ok(not result, 'pcall() without args: bad status') 13 | test:like(err, 'value expected', 'pcall() without args: error message') 14 | 15 | test:done(true) 16 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-783-fold--0.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate LuaJIT's incorrect fold optimization 4 | -- x - (-0) ==> x. 5 | -- See also https://github.com/LuaJIT/LuaJIT/issues/783. 6 | local test = tap.test('lj-783-fold--0'):skipcond({ 7 | ['Test requires JIT enabled'] = not jit.status(), 8 | }) 9 | 10 | test:plan(2) 11 | 12 | -- XXX: Use the variable to avoid folding during parsing. 13 | local minus_zero = -0 14 | local results = {} 15 | 16 | jit.opt.start('hotloop=1') 17 | 18 | for i = 1, 4 do 19 | results[i] = tostring(minus_zero - (-0)) 20 | end 21 | 22 | -- Fold optimization x - (-0) ==> x is INVALID for x = -0 in FP 23 | -- arithmetic. Its result is -0 instead of +0. 24 | 25 | test:is(results[1], '0', 'correct VM value for -0 - (-0)') 26 | test:samevalues(results, '-0 folding in simplify_numsub_k') 27 | 28 | test:done(true) 29 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-802-panic-at-mcode-protfail/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) 2 | BuildTestCLib(mymprotect mymprotect.c ${test_name}.test.lua) 3 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-802-panic-at-mcode-protfail/mymprotect.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int mprotect(void *addr, size_t len, int prot) 4 | { 5 | return -1; 6 | } 7 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-802-panic-at-mcode-protfail/script.lua: -------------------------------------------------------------------------------- 1 | jit.opt.start('hotloop=1') 2 | 3 | -- Run a simple loop that triggers on trace assembling. 4 | local a = 0 5 | for i = 1, 3 do 6 | a = a + i 7 | end 8 | 9 | -- XXX: Just a simple contract output in case neither the panic at 10 | -- , nor crash occurs (see for LUAJIT_UNPROTECT_MCODE in 11 | -- lj_mcode.c for more info). 12 | io.write(arg[1]) 13 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-833-fold-conv-from-num.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- XXX: Test the behaviour of fold optimizations from numbers to 4 | -- different integer types. The test itself doesn't fail before 5 | -- the commit since these changes relate only to version 2.0. 6 | 7 | local test = tap.test('lj-833-fold-conv-from-num'):skipcond({ 8 | ['Test requires JIT enabled'] = not jit.status(), 9 | }) 10 | 11 | local ffi = require('ffi') 12 | 13 | test:plan(3) 14 | 15 | local arr_i64 = ffi.new('int64_t [2]') 16 | local arr_u64 = ffi.new('uint64_t [2]') 17 | local arr_u32 = ffi.new('uint32_t [2]') 18 | 19 | jit.opt.start('hotloop=1') 20 | 21 | for _ = 1, 4 do 22 | -- Test conversion to type (at store). Also, check the 23 | -- conversion from number to int64_t at C array indexing. 24 | arr_i64[1.1] = 1.1 25 | arr_u64[1.1] = 1.1 26 | arr_u32[1.1] = 1.1 27 | end 28 | 29 | test:is(arr_i64[1], 1LL, 'correct conversion to int64_t') 30 | test:is(arr_u64[1], 1ULL, 'correct conversion to uint64_t') 31 | test:is(arr_u32[1], 1ULL, 'correct conversion to uint32_t') 32 | 33 | test:done(true) 34 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-839-concat-recording.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('lj-839-concat-recording'):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | }) 5 | test:plan(1) 6 | 7 | -- Test file to demonstrate LuaJIT overriding stack slots without 8 | -- restoration during the recording of the concat metamethod. 9 | -- See also: https://github.com/LuaJIT/LuaJIT/issues/839. 10 | 11 | -- Setup value with the `__concat` metamethod. 12 | local v1 = setmetatable({}, { 13 | __concat = function(_, op2) return op2 end, 14 | }); 15 | 16 | jit.opt.start('hotloop=1') 17 | local result 18 | for _ = 1, 4 do 19 | -- `savetv` in `rec_cat` handles only up to 5 slots. 20 | result = v1 .. '' .. '' .. '' .. '' .. 'canary' 21 | end 22 | 23 | -- Failure results in a LuaJIT assertion failure. 24 | -- The issue is GC64-specific, yet it is still being tested for 25 | -- other builds. 26 | test:is(result, 'canary', 'correct stack restoration') 27 | test:done(true) 28 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-859-math-ceil-sign.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | 3 | -- Test file to demonstrate the incorrect LuaJIT's behaviour 4 | -- for `math.ceil(x)` when argument `x`: -1 < x < -0.5. 5 | -- See also https://github.com/LuaJIT/LuaJIT/issues/859. 6 | 7 | local test = tap.test('lj-859-math-ceil-sign') 8 | 9 | test:plan(1) 10 | 11 | local IS_DUALNUM = tostring(tonumber('-0')) ~= tostring(-0) 12 | local IS_X86_64 = jit.arch == 'x86' or jit.arch == 'x64' 13 | 14 | -- Use `tostring()` to compare the sign of the returned value. 15 | -- Take any value from the mentioned range. The chosen one is 16 | -- mentioned in the commit message. 17 | test:ok((IS_DUALNUM and IS_X86_64) or tostring(math.ceil(-0.9)) == '-0', 18 | 'correct zero sign') 19 | 20 | test:done(true) 21 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-864-varg-rec-base-offset.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | -- Test file to demonstrate LuaJIT misbehaviour during recording 3 | -- BC_VARG with nvarargs >= nresults in GC64 mode. 4 | -- See also https://github.com/LuaJIT/LuaJIT/issues/864, 5 | -- https://github.com/tarantool/tarantool/issues/7172. 6 | local test = tap.test('lj-864-varg-rec-base-offset'):skipcond({ 7 | ['Test requires JIT enabled'] = not jit.status(), 8 | }) 9 | 10 | test:plan(1) 11 | 12 | jit.opt.start('hotloop=1') 13 | 14 | local function test_rec_varg(...) 15 | local trace_value, interp_value 16 | for _ = 1, 3 do 17 | trace_value = ... 18 | end 19 | interp_value = ... 20 | return trace_value == interp_value 21 | end 22 | 23 | -- Test case for nvarargs >= nresults. Equality is not suitable 24 | -- due to failing assertion guard for type of loaded vararg slot. 25 | test:ok(test_rec_varg(42, 0), 'correct BC_VARG recording') 26 | 27 | test:done(true) 28 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-913-stackoverflow-stitched-trace.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | -- Test to demonstrate the incorrect LuaJIT behavior when exiting 3 | -- from a snapshot for stitched trace. 4 | local test = tap.test('lj-913-stackoverflow-stitched-trace'):skipcond({ 5 | ['Test requires JIT enabled'] = not jit.status(), 6 | }) 7 | 8 | test:plan(3) 9 | 10 | -- Recursion to cause stack overflow. 11 | local function callee() 12 | -- `math.fmod()` is NYI, so trace will be stitched here. 13 | math.fmod(42, 42) 14 | callee() 15 | end 16 | 17 | local st, err = pcall(callee) 18 | 19 | test:ok(true, 'assertion is not triggered') 20 | test:ok(not st, 'error happened') 21 | test:like(err, 'stack overflow', 'stack overflow happened') 22 | 23 | test:done(true) 24 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-918-fma-optimization.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('lj-918-fma-optimization'):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | }) 5 | 6 | test:plan(3) 7 | 8 | local function jit_opt_is_on(flag) 9 | for _, opt in ipairs({jit.status()}) do 10 | if opt == flag then 11 | return true 12 | end 13 | end 14 | return false 15 | end 16 | 17 | test:ok(not jit_opt_is_on('fma'), 'FMA is disabled by default') 18 | 19 | local ok, _ = pcall(jit.opt.start, '+fma') 20 | 21 | test:ok(ok, 'fma flag is recognized') 22 | 23 | test:ok(jit_opt_is_on('fma'), 'FMA is enabled after jit.opt.start()') 24 | 25 | test:done(true) 26 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-946-print-errors-from-gc-fin-default.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('lj-flush-on-trace'):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | }) 5 | 6 | test:plan(1) 7 | 8 | local script = require('utils').exec.makecmd(arg, { redirect = '2>&1' }) 9 | local output = script() 10 | test:like(output, 'ERROR in finalizer:', 'error handler called') 11 | test:done(true) 12 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-946-print-errors-from-gc-fin-default/script.lua: -------------------------------------------------------------------------------- 1 | local ffi = require('ffi') 2 | 3 | local function new_bad_cdata() 4 | return ffi.gc(ffi.new('char [?]', 1024), 'uncallable string') 5 | end 6 | 7 | local function test_f() 8 | collectgarbage('collect') 9 | -- Make GC aggressive enough to end the atomic phase before 10 | -- exiting the trace. 11 | collectgarbage('setstepmul', 400) 12 | -- The number of iterations is empirical, just big enough for 13 | -- the issue to strike. 14 | for _ = 1, 10000 do 15 | new_bad_cdata() 16 | end 17 | end 18 | 19 | jit.opt.start('hotloop=1') 20 | local status = pcall(test_f) 21 | -- We have to stop GC now because any step raises the error due to 22 | -- cursed cdata objects. 23 | collectgarbage('stop') 24 | assert(status, 'error is not rethrown') 25 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-962-stack-overflow-report.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | -- The test reproduces the problem only for GC64 mode with enabled 3 | -- JIT. 4 | local test = tap.test('lj-962-stack-overflow-report') 5 | test:plan(1) 6 | 7 | local LUABIN = require('utils').exec.luabin(arg) 8 | local SCRIPT = arg[0]:gsub('%.test%.lua$', '/script.lua') 9 | local output = io.popen(LUABIN .. ' 2>&1 ' .. SCRIPT, 'r'):read('*all') 10 | test:like(output, 'stack overflow', 'stack overflow reported correctly') 11 | test:done(true) 12 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-962-stack-overflow-report/script.lua: -------------------------------------------------------------------------------- 1 | -- XXX: Function `f` is global to avoid using an additional stack 2 | -- slot. 3 | -- luacheck: no global 4 | f = function() f() end; f() 5 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-flush-on-trace/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) 2 | BuildTestCLib(libflush libflush.c ${test_name}.test.lua) 3 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-flush-on-trace/libflush.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct flush { 5 | lua_State *L; /* Coroutine saved to change JIT mode */ 6 | int trigger; /* Trigger for flushing all traces */ 7 | }; 8 | 9 | void flush(struct flush *state, int i) 10 | { 11 | if (i < state->trigger) 12 | return; 13 | 14 | /* Trace flushing is triggered */ 15 | (void)luaJIT_setmode(state->L, 0, LUAJIT_MODE_ENGINE|LUAJIT_MODE_FLUSH); 16 | } 17 | 18 | static int init(lua_State *L) 19 | { 20 | struct flush *state = lua_newuserdata(L, sizeof(struct flush)); 21 | 22 | state->L = L; 23 | state->trigger = lua_tonumber(L, 1); 24 | return 1; 25 | } 26 | 27 | LUA_API int luaopen_libflush(lua_State *L) 28 | { 29 | lua_pushcfunction(L, init); 30 | return 1; 31 | } 32 | -------------------------------------------------------------------------------- /test/tarantool-tests/lj-flush-on-trace/script.lua: -------------------------------------------------------------------------------- 1 | local hotloop = assert(arg[1], 'hotloop argument is missing') 2 | local trigger = assert(arg[2], 'trigger argument is missing') 3 | 4 | local ffi = require('ffi') 5 | local ffiflush = ffi.load('libflush') 6 | ffi.cdef('void flush(struct flush *state, int i)') 7 | 8 | -- Save the current coroutine and set the value to trigger 9 | -- call the Lua routine instead of C implementation. 10 | local flush = require('libflush')(trigger) 11 | 12 | -- Depending on trigger and hotloop values the following contexts 13 | -- are possible: 14 | -- * if trigger <= hotloop -> trace recording is aborted 15 | -- * if trigger > hotloop -> trace is recorded but execution 16 | -- leads to panic 17 | jit.opt.start(string.format('hotloop=%d', hotloop)) 18 | 19 | for i = 0, trigger + hotloop do 20 | ffiflush.flush(flush, i) 21 | end 22 | -- Panic didn't occur earlier. 23 | io.write('LJ flush still works') 24 | -------------------------------------------------------------------------------- /test/tarantool-tests/math-modf.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local tnew = require('table.new') 3 | local test = tap.test('math-modf'):skipcond({ 4 | ['Test requires JIT enabled'] = not jit.status(), 5 | }) 6 | 7 | test:plan(1) 8 | 9 | local function isnan(x) 10 | return x ~= x 11 | end 12 | 13 | local function array_is_consistent(res) 14 | for i = 1, #res - 1 do 15 | if res[i] ~= res[i + 1] and not (isnan(res[i]) and isnan(res[i + 1])) then 16 | return false 17 | end 18 | end 19 | return true 20 | end 21 | 22 | jit.opt.start('hotloop=1') 23 | 24 | local modf = math.modf 25 | local inf = math.huge 26 | 27 | local r1 = tnew(4, 0) 28 | local r2 = tnew(4, 0) 29 | 30 | for i = 1, 3 do 31 | r1[i], r2[i] = modf(inf) 32 | end 33 | 34 | test:ok(array_is_consistent(r1) and array_is_consistent(r2), 'wrong modf') 35 | 36 | test:done(true) 37 | -------------------------------------------------------------------------------- /test/tarantool-tests/or-144-gc64-asmref-l.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('or-144-gc64-asmref-l'):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | }) 5 | 6 | test:plan(1) 7 | 8 | -- luacheck: push no max_comment_line_length 9 | -- 10 | -- Test file to demonstrate LuaJIT `IR_LREF` assembling incorrect 11 | -- behaviour. 12 | -- See also: 13 | -- * https://github.com/openresty/lua-resty-core/issues/144. 14 | -- * https://www.freelists.org/post/luajit/Consistent-SEGV-on-x64-with-the-latest-LuaJIT-v21-GC64-mode. 15 | -- 16 | -- luacheck: pop 17 | 18 | jit.opt.start('hotloop=1') 19 | 20 | local global_env 21 | local _ 22 | for i = 1, 4 do 23 | -- Test `IR_LREF` assembling: using `ASMREF_L` (`REF_NIL`). 24 | global_env = getfenv(0) 25 | -- Need to reuse the register, to cause emitting of `mov` 26 | -- instruction (see `ra_left()` in ). 27 | _ = tostring(i) 28 | end 29 | 30 | test:ok(global_env == getfenv(0), 'IR_LREF assembling correctness') 31 | 32 | test:done(true) 33 | -------------------------------------------------------------------------------- /test/tarantool-tests/profilers/gh-5813-resolving-of-c-symbols/both/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if (NOT(CMAKE_SYSTEM_NAME STREQUAL "Darwin")) 2 | BuildTestCLib(resboth resboth.c 3 | profilers/gh-5813-resolving-of-c-symbols.test.lua 4 | ) 5 | # Unfortunately, command is introduced 6 | # since CMake 3.13, so we can't use it now considering ancient 7 | # distros support. Just build linker flags by hands. 8 | set(CMAKE_SHARED_LINKER_FLAGS 9 | "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--hash-style=both" 10 | ) 11 | endif() 12 | -------------------------------------------------------------------------------- /test/tarantool-tests/profilers/gh-5813-resolving-of-c-symbols/both/resboth.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int allocate_string(lua_State *L) { 5 | lua_pushstring(L, "test string"); 6 | return 1; 7 | } 8 | 9 | static const struct luaL_Reg resboth [] = { 10 | {"allocate_string", allocate_string}, 11 | {NULL, NULL} 12 | }; 13 | 14 | int luaopen_resboth(lua_State *L) { 15 | luaL_register(L, "resboth", resboth); 16 | return 1; 17 | } 18 | -------------------------------------------------------------------------------- /test/tarantool-tests/profilers/gh-5813-resolving-of-c-symbols/gnuhash/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if (NOT(CMAKE_SYSTEM_NAME STREQUAL "Darwin")) 2 | BuildTestCLib(resgnuhash resgnuhash.c 3 | profilers/gh-5813-resolving-of-c-symbols.test.lua 4 | ) 5 | # Unfortunately, command is introduced 6 | # since CMake 3.13, so we can't use it now considering ancient 7 | # distros support. Just build linker flags by hands. 8 | set(CMAKE_SHARED_LINKER_FLAGS 9 | "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--hash-style=gnu" 10 | ) 11 | endif() 12 | -------------------------------------------------------------------------------- /test/tarantool-tests/profilers/gh-5813-resolving-of-c-symbols/gnuhash/resgnuhash.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int allocate_string(lua_State *L) { 5 | lua_pushstring(L, "test string"); 6 | return 1; 7 | } 8 | 9 | static const struct luaL_Reg resgnuhash [] = { 10 | {"allocate_string", allocate_string}, 11 | {NULL, NULL} 12 | }; 13 | 14 | int luaopen_resgnuhash(lua_State *L) { 15 | luaL_register(L, "resgnuhash", resgnuhash); 16 | return 1; 17 | } 18 | -------------------------------------------------------------------------------- /test/tarantool-tests/profilers/gh-5813-resolving-of-c-symbols/hash/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if (NOT(CMAKE_SYSTEM_NAME STREQUAL "Darwin")) 2 | BuildTestCLib(reshash reshash.c 3 | profilers/gh-5813-resolving-of-c-symbols.test.lua 4 | ) 5 | # Unfortunately, command is introduced 6 | # since CMake 3.13, so we can't use it now considering ancient 7 | # distros support. Just build linker flags by hands. 8 | set(CMAKE_SHARED_LINKER_FLAGS 9 | "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--hash-style=sysv" 10 | ) 11 | endif() 12 | -------------------------------------------------------------------------------- /test/tarantool-tests/profilers/gh-5813-resolving-of-c-symbols/hash/reshash.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int allocate_string(lua_State *L) { 5 | lua_pushstring(L, "test string"); 6 | return 1; 7 | } 8 | 9 | static const struct luaL_Reg reshash [] = { 10 | {"allocate_string", allocate_string}, 11 | {NULL, NULL} 12 | }; 13 | 14 | int luaopen_reshash(lua_State *L) { 15 | luaL_register(L, "reshash", reshash); 16 | return 1; 17 | } 18 | -------------------------------------------------------------------------------- /test/tarantool-tests/profilers/gh-5813-resolving-of-c-symbols/stripped/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if (NOT(CMAKE_SYSTEM_NAME STREQUAL "Darwin")) 2 | BuildTestCLib(resstripped resstripped.c 3 | profilers/gh-5813-resolving-of-c-symbols.test.lua 4 | ) 5 | # Unfortunately, command is introduced 6 | # since CMake 3.13, so we can't use it now considering ancient 7 | # distros support. Just build linker flags by hands. 8 | set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -s") 9 | endif() 10 | -------------------------------------------------------------------------------- /test/tarantool-tests/profilers/gh-5813-resolving-of-c-symbols/stripped/resstripped.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int allocate_string(lua_State *L) { 5 | lua_pushstring(L, "test string"); 6 | return 1; 7 | } 8 | 9 | static const struct luaL_Reg resstripped [] = { 10 | {"allocate_string", allocate_string}, 11 | {NULL, NULL} 12 | }; 13 | 14 | int luaopen_resstripped(lua_State *L) { 15 | luaL_register(L, "resstripped", resstripped); 16 | return 1; 17 | } 18 | -------------------------------------------------------------------------------- /test/tarantool-tests/profilers/misclib-memprof-lapi-disabled.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('misclib-memprof-lapi-disabled'):skipcond({ 3 | ['Memprof is enabled'] = not os.getenv('LUAJIT_DISABLE_MEMPROF'), 4 | }) 5 | 6 | test:plan(6) 7 | 8 | -- Attempt to start memprof when it is disabled. 9 | local res, err, errno = misc.memprof.start() 10 | test:is(res, nil, 'result status on start when memprof is disabled') 11 | test:ok(err:match('profiler is disabled'), 12 | 'error on start when memprof is disabled') 13 | test:ok(type(errno) == 'number', 'errno on start when memprof is disabled') 14 | 15 | -- Attempt to stop memprof when it is disabled. 16 | res, err, errno = misc.memprof.stop() 17 | test:is(res, nil, 'result status on stop when memprof is disabled') 18 | test:ok(err:match('profiler is disabled'), 19 | 'error on stop when memprof is disabled') 20 | test:ok(type(errno) == 'number', 'errno on start when memprof is disabled') 21 | 22 | test:done(true) 23 | -------------------------------------------------------------------------------- /test/tarantool-tests/unit-jit-parse-abort.test.lua: -------------------------------------------------------------------------------- 1 | local tap = require('tap') 2 | local test = tap.test('unit-jit-parse-abort'):skipcond({ 3 | ['Test requires JIT enabled'] = not jit.status(), 4 | ['Disabled on *BSD due to #4819'] = jit.os == 'BSD', 5 | }) 6 | 7 | local jparse = require('utils').jit.parse 8 | 9 | -- XXX: Avoid other traces compilation due to hotcount collisions 10 | -- for predictable results. 11 | jit.off() 12 | jit.flush() 13 | 14 | test:plan(1) 15 | 16 | jit.on() 17 | -- We only need the abort reason in the test. 18 | jparse.start('t') 19 | 20 | -- XXX: A trace always has at least 3 IR constants: for `nil`, 21 | -- `false`, and `true`. Always fails to record with the set 22 | -- `maxirconst` limit. 23 | jit.opt.start('hotloop=1', 'maxirconst=1') 24 | 25 | for _ = 1, 3 do end 26 | 27 | local _, aborted_traces = jparse.finish() 28 | 29 | jit.off() 30 | 31 | assert(aborted_traces and aborted_traces[1], 'aborted trace is persisted') 32 | 33 | -- We tried to compile only one trace. 34 | local reason = aborted_traces[1][1].abort_reason 35 | 36 | test:like(reason, 'trace too long', 'abort reason is correct') 37 | 38 | test:done(true) 39 | -------------------------------------------------------------------------------- /test/tarantool-tests/utils/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND tests 2 | lj-1166-error-stitch-oom-ir-buff.test.lua 3 | lj-1166-error-stitch-oom-snap-buff.test.lua 4 | lj-1247-fin-tab-rehashing-on-trace.test.lua 5 | lj-1298-oom-on-concat-recording.test.lua 6 | ) 7 | BuildTestCLib(allocinject allocinject.c "${tests}") 8 | -------------------------------------------------------------------------------- /test/tarantool-tests/utils/gc.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local ffi = require('ffi') 4 | 5 | local LJ_GC_BLACK = 0x04 6 | local LJ_STR_HASHLEN = 8 7 | local GCref = ffi.abi('gc64') and 'uint64_t' or 'uint32_t' 8 | 9 | ffi.cdef([[ 10 | typedef struct { 11 | ]]..GCref..[[ nextgc; 12 | uint8_t marked; 13 | uint8_t gct; 14 | /* Need this fields for correct alignment and sizeof. */ 15 | uint8_t misc1; 16 | uint8_t misc2; 17 | } GCHeader; 18 | ]]) 19 | 20 | function M.isblack(obj) 21 | local objtype = type(obj) 22 | local address = objtype == 'string' 23 | -- XXX: get strdata first and go back to GCHeader. 24 | and ffi.cast('char *', obj) - (ffi.sizeof('GCHeader') + LJ_STR_HASHLEN) 25 | -- XXX: FFI ABI forbids to cast functions objects 26 | -- to non-functional pointers, but we can get their address 27 | -- via tostring. 28 | or tonumber((tostring(obj):gsub(objtype .. ': ', ''))) 29 | local marked = ffi.cast('GCHeader *', address).marked 30 | return bit.band(marked, LJ_GC_BLACK) == LJ_GC_BLACK 31 | end 32 | 33 | return M 34 | -------------------------------------------------------------------------------- /test/tarantool-tests/utils/init.lua: -------------------------------------------------------------------------------- 1 | return setmetatable({}, { 2 | __index = function(self, k) 3 | assert(type(k) == 'string', "The name of `utils' submodule is required") 4 | rawset(self, k, require(('utils.%s'):format(k))) 5 | return rawget(self, k) 6 | end, 7 | }) 8 | -------------------------------------------------------------------------------- /test/tarantool-tests/utils/jit/const.lua: -------------------------------------------------------------------------------- 1 | return { 2 | -- XXX: Max nins is limited by max IRRef, that equals to 3 | -- REF_DROP - REF_BIAS. Unfortunately, these constants are not 4 | -- provided to Lua space, so we ought to make some math: 5 | -- * REF_DROP = 0xffff 6 | -- * REF_BIAS = 0x8000 7 | maxnins = 0xffff - 0x8000, 8 | } 9 | -------------------------------------------------------------------------------- /test/tarantool-tests/utils/jit/init.lua: -------------------------------------------------------------------------------- 1 | return setmetatable({}, { 2 | __index = function(self, k) 3 | assert(type(k) == 'string', "The name of `utils.jit' submodule is required") 4 | rawset(self, k, require(('utils.jit.%s'):format(k))) 5 | return rawget(self, k) 6 | end, 7 | }) 8 | -------------------------------------------------------------------------------- /test/tarantool-tests/utils/tools.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.profilename(name) 4 | local vardir = os.getenv('LUAJIT_TEST_VARDIR') 5 | -- Replace pattern will change directory name of the generated 6 | -- profile to LUAJIT_TEST_VARDIR if it is set in the process 7 | -- environment. Otherwise, the original dirname is left intact. 8 | -- As a basename for this profile the test name is concatenated 9 | -- with the name given as an argument. 10 | local replacepattern = ('%s/%s-%s'):format(vardir or '%1', '%2', name) 11 | -- XXX: return only the resulting string. 12 | return (arg[0]:gsub('^(.+)/([^/]+)%.test%.lua$', replacepattern)) 13 | end 14 | 15 | -- Reads a file located at a specified path and returns its 16 | -- content. 17 | function M.read_file(path) 18 | local file = assert(io.open(path), 'cannot open a file') 19 | local content = file:read('*a') 20 | file:close() 21 | return content 22 | end 23 | 24 | return M 25 | -------------------------------------------------------------------------------- /tools/utils/evread.lua: -------------------------------------------------------------------------------- 1 | local bufread = require('utils.bufread') 2 | local symtab = require('utils.symtab') 3 | 4 | local function make_error_handler(fmt, inputfile) 5 | return function(err) 6 | io.stderr:write(string.format(fmt, inputfile)) 7 | io.stderr:write(string.format('\n\t%s\n', err)) 8 | os.exit(1, true) 9 | end 10 | end 11 | 12 | return function(parser, inputfile) 13 | local _, reader = xpcall( 14 | bufread.new, 15 | make_error_handler('Failed to open %s.', inputfile), 16 | inputfile 17 | ) 18 | 19 | local _, symbols = xpcall( 20 | symtab.parse, 21 | make_error_handler('Failed to parse symtab from %s.', inputfile), 22 | reader 23 | ) 24 | 25 | local _, events = xpcall( 26 | parser, 27 | make_error_handler('Failed to parse profile data from %s.', inputfile), 28 | reader, 29 | symbols 30 | ) 31 | return events, symbols 32 | end 33 | --------------------------------------------------------------------------------