immunio 0.15.4 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +0 -27
- data/ext/immunio/Rakefile +9 -0
- data/lib/immunio/plugins/active_record.rb +1 -1
- data/lib/immunio/plugins/active_record_relation.rb +1 -1
- data/lib/immunio/plugins/environment_reporter.rb +20 -0
- data/lib/immunio/rufus_lua_ext/ref.rb +1 -3
- data/lib/immunio/version.rb +1 -1
- data/lib/immunio/vm.rb +1 -2
- data/lua-hooks/Makefile +97 -0
- data/lua-hooks/ext/all.c +41 -52
- data/lua-hooks/ext/all.o +0 -0
- data/lua-hooks/ext/libinjection/libinjection_html5.o +0 -0
- data/lua-hooks/ext/libinjection/libinjection_sqli.o +0 -0
- data/lua-hooks/ext/libinjection/libinjection_xss.o +0 -0
- data/lua-hooks/ext/libinjection/lualib.c +2 -2
- data/lua-hooks/ext/lpeg/lpcap.c +2 -2
- data/lua-hooks/ext/lpeg/lpcap.o +0 -0
- data/lua-hooks/ext/lpeg/lpcode.c +2 -2
- data/lua-hooks/ext/lpeg/lpcode.h +1 -1
- data/lua-hooks/ext/lpeg/lpcode.o +0 -0
- data/lua-hooks/ext/lpeg/lpprint.o +0 -0
- data/lua-hooks/ext/lpeg/lptree.c +2 -2
- data/lua-hooks/ext/lpeg/lptypes.h +1 -1
- data/lua-hooks/ext/lpeg/lpvm.c +2 -2
- data/lua-hooks/ext/lpeg/lpvm.o +0 -0
- data/lua-hooks/ext/lua-cmsgpack/lua_cmsgpack.c +16 -3
- data/lua-hooks/ext/lua-snapshot/snapshot.c +14 -7
- data/lua-hooks/ext/luajit/COPYRIGHT +56 -0
- data/lua-hooks/ext/luajit/Makefile +159 -0
- data/lua-hooks/ext/luajit/README +16 -0
- data/lua-hooks/ext/luajit/doc/bluequad-print.css +166 -0
- data/lua-hooks/ext/luajit/doc/bluequad.css +325 -0
- data/lua-hooks/ext/luajit/doc/changes.html +804 -0
- data/lua-hooks/ext/luajit/doc/contact.html +104 -0
- data/lua-hooks/ext/luajit/doc/ext_c_api.html +189 -0
- data/lua-hooks/ext/luajit/doc/ext_ffi.html +332 -0
- data/lua-hooks/ext/luajit/doc/ext_ffi_api.html +570 -0
- data/lua-hooks/ext/luajit/doc/ext_ffi_semantics.html +1261 -0
- data/lua-hooks/ext/luajit/doc/ext_ffi_tutorial.html +603 -0
- data/lua-hooks/ext/luajit/doc/ext_jit.html +201 -0
- data/lua-hooks/ext/luajit/doc/ext_profiler.html +365 -0
- data/lua-hooks/ext/luajit/doc/extensions.html +448 -0
- data/lua-hooks/ext/luajit/doc/faq.html +186 -0
- data/lua-hooks/ext/luajit/doc/img/contact.png +0 -0
- data/lua-hooks/ext/luajit/doc/install.html +659 -0
- data/lua-hooks/ext/luajit/doc/luajit.html +236 -0
- data/lua-hooks/ext/luajit/doc/running.html +309 -0
- data/lua-hooks/ext/luajit/doc/status.html +118 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_arm.h +456 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_arm.lua +1125 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_arm64.h +518 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_arm64.lua +1166 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_mips.h +416 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_mips.lua +953 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_ppc.h +419 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_ppc.lua +1919 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_proto.h +83 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_x64.lua +12 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_x86.h +471 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_x86.lua +1945 -0
- data/lua-hooks/ext/luajit/dynasm/dynasm.lua +1094 -0
- data/lua-hooks/ext/luajit/etc/luajit.1 +88 -0
- data/lua-hooks/ext/luajit/etc/luajit.pc +25 -0
- data/lua-hooks/ext/luajit/src/Makefile +697 -0
- data/lua-hooks/ext/luajit/src/Makefile.dep +244 -0
- data/lua-hooks/ext/luajit/src/host/README +4 -0
- data/lua-hooks/ext/luajit/src/host/buildvm +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm.c +518 -0
- data/lua-hooks/ext/luajit/src/host/buildvm.h +105 -0
- data/lua-hooks/ext/luajit/src/host/buildvm.o +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_arch.h +7449 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_asm.c +345 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_asm.o +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_fold.c +229 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_fold.o +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_lib.c +457 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_lib.o +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_libbc.h +45 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_peobj.c +368 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_peobj.o +0 -0
- data/lua-hooks/ext/luajit/src/host/genlibbc.lua +197 -0
- data/lua-hooks/ext/luajit/src/host/genminilua.lua +428 -0
- data/lua-hooks/ext/luajit/src/host/minilua +0 -0
- data/lua-hooks/ext/luajit/src/host/minilua.c +7770 -0
- data/lua-hooks/ext/luajit/src/host/minilua.o +0 -0
- data/lua-hooks/ext/luajit/src/jit/bc.lua +190 -0
- data/lua-hooks/ext/luajit/src/jit/bcsave.lua +661 -0
- data/lua-hooks/ext/luajit/src/jit/dis_arm.lua +689 -0
- data/lua-hooks/ext/luajit/src/jit/dis_mips.lua +428 -0
- data/lua-hooks/ext/luajit/src/jit/dis_mipsel.lua +17 -0
- data/lua-hooks/ext/luajit/src/jit/dis_ppc.lua +591 -0
- data/lua-hooks/ext/luajit/src/jit/dis_x64.lua +17 -0
- data/lua-hooks/ext/luajit/src/jit/dis_x86.lua +838 -0
- data/lua-hooks/ext/luajit/src/jit/dump.lua +706 -0
- data/lua-hooks/ext/luajit/src/jit/p.lua +310 -0
- data/lua-hooks/ext/luajit/src/jit/v.lua +170 -0
- data/lua-hooks/ext/luajit/src/jit/vmdef.lua +362 -0
- data/lua-hooks/ext/luajit/src/jit/zone.lua +45 -0
- data/lua-hooks/ext/{lua → luajit/src}/lauxlib.h +10 -17
- data/lua-hooks/ext/luajit/src/lib_aux.c +356 -0
- data/lua-hooks/ext/luajit/src/lib_aux.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_aux_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_base.c +664 -0
- data/lua-hooks/ext/luajit/src/lib_base.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_base_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_bit.c +180 -0
- data/lua-hooks/ext/luajit/src/lib_bit.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_bit_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_debug.c +405 -0
- data/lua-hooks/ext/luajit/src/lib_debug.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_debug_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_ffi.c +872 -0
- data/lua-hooks/ext/luajit/src/lib_ffi.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_ffi_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_init.c +55 -0
- data/lua-hooks/ext/luajit/src/lib_init.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_init_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_io.c +541 -0
- data/lua-hooks/ext/luajit/src/lib_io.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_io_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_jit.c +767 -0
- data/lua-hooks/ext/luajit/src/lib_jit.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_jit_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_math.c +230 -0
- data/lua-hooks/ext/luajit/src/lib_math.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_math_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_os.c +292 -0
- data/lua-hooks/ext/luajit/src/lib_os.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_os_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_package.c +610 -0
- data/lua-hooks/ext/luajit/src/lib_package.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_package_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_string.c +752 -0
- data/lua-hooks/ext/luajit/src/lib_string.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_string_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_table.c +307 -0
- data/lua-hooks/ext/luajit/src/lib_table.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_table_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/libluajit.a +0 -0
- data/lua-hooks/ext/luajit/src/libluajit.so +0 -0
- data/lua-hooks/ext/luajit/src/lj.supp +26 -0
- data/lua-hooks/ext/luajit/src/lj_alloc.c +1398 -0
- data/lua-hooks/ext/luajit/src/lj_alloc.h +17 -0
- data/lua-hooks/ext/luajit/src/lj_alloc.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_alloc_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_api.c +1210 -0
- data/lua-hooks/ext/luajit/src/lj_api.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_api_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_arch.h +509 -0
- data/lua-hooks/ext/luajit/src/lj_asm.c +2278 -0
- data/lua-hooks/ext/luajit/src/lj_asm.h +17 -0
- data/lua-hooks/ext/luajit/src/lj_asm.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_asm_arm.h +2217 -0
- data/lua-hooks/ext/luajit/src/lj_asm_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_asm_mips.h +1833 -0
- data/lua-hooks/ext/luajit/src/lj_asm_ppc.h +2015 -0
- data/lua-hooks/ext/luajit/src/lj_asm_x86.h +2634 -0
- data/lua-hooks/ext/luajit/src/lj_bc.c +14 -0
- data/lua-hooks/ext/luajit/src/lj_bc.h +265 -0
- data/lua-hooks/ext/luajit/src/lj_bc.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bc_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bcdef.h +220 -0
- data/lua-hooks/ext/luajit/src/lj_bcdump.h +68 -0
- data/lua-hooks/ext/luajit/src/lj_bcread.c +457 -0
- data/lua-hooks/ext/luajit/src/lj_bcread.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bcread_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bcwrite.c +361 -0
- data/lua-hooks/ext/luajit/src/lj_bcwrite.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bcwrite_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_buf.c +234 -0
- data/lua-hooks/ext/luajit/src/lj_buf.h +105 -0
- data/lua-hooks/ext/luajit/src/lj_buf.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_buf_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_carith.c +429 -0
- data/lua-hooks/ext/luajit/src/lj_carith.h +37 -0
- data/lua-hooks/ext/luajit/src/lj_carith.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_carith_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ccall.c +984 -0
- data/lua-hooks/ext/luajit/src/lj_ccall.h +178 -0
- data/lua-hooks/ext/luajit/src/lj_ccall.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ccall_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ccallback.c +712 -0
- data/lua-hooks/ext/luajit/src/lj_ccallback.h +25 -0
- data/lua-hooks/ext/luajit/src/lj_ccallback.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ccallback_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cconv.c +752 -0
- data/lua-hooks/ext/luajit/src/lj_cconv.h +70 -0
- data/lua-hooks/ext/luajit/src/lj_cconv.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cconv_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cdata.c +288 -0
- data/lua-hooks/ext/luajit/src/lj_cdata.h +76 -0
- data/lua-hooks/ext/luajit/src/lj_cdata.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cdata_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_char.c +43 -0
- data/lua-hooks/ext/luajit/src/lj_char.h +42 -0
- data/lua-hooks/ext/luajit/src/lj_char.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_char_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_clib.c +418 -0
- data/lua-hooks/ext/luajit/src/lj_clib.h +29 -0
- data/lua-hooks/ext/luajit/src/lj_clib.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_clib_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cparse.c +1862 -0
- data/lua-hooks/ext/luajit/src/lj_cparse.h +65 -0
- data/lua-hooks/ext/luajit/src/lj_cparse.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cparse_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_crecord.c +1834 -0
- data/lua-hooks/ext/luajit/src/lj_crecord.h +38 -0
- data/lua-hooks/ext/luajit/src/lj_crecord.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_crecord_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ctype.c +635 -0
- data/lua-hooks/ext/luajit/src/lj_ctype.h +461 -0
- data/lua-hooks/ext/luajit/src/lj_ctype.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ctype_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_debug.c +699 -0
- data/lua-hooks/ext/luajit/src/lj_debug.h +65 -0
- data/lua-hooks/ext/luajit/src/lj_debug.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_debug_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_def.h +365 -0
- data/lua-hooks/ext/luajit/src/lj_dispatch.c +557 -0
- data/lua-hooks/ext/luajit/src/lj_dispatch.h +138 -0
- data/lua-hooks/ext/luajit/src/lj_dispatch.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_dispatch_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_emit_arm.h +356 -0
- data/lua-hooks/ext/luajit/src/lj_emit_mips.h +211 -0
- data/lua-hooks/ext/luajit/src/lj_emit_ppc.h +238 -0
- data/lua-hooks/ext/luajit/src/lj_emit_x86.h +462 -0
- data/lua-hooks/ext/luajit/src/lj_err.c +794 -0
- data/lua-hooks/ext/luajit/src/lj_err.h +41 -0
- data/lua-hooks/ext/luajit/src/lj_err.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_err_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_errmsg.h +190 -0
- data/lua-hooks/ext/luajit/src/lj_ff.h +18 -0
- data/lua-hooks/ext/luajit/src/lj_ffdef.h +209 -0
- data/lua-hooks/ext/luajit/src/lj_ffrecord.c +1247 -0
- data/lua-hooks/ext/luajit/src/lj_ffrecord.h +24 -0
- data/lua-hooks/ext/luajit/src/lj_ffrecord.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ffrecord_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_folddef.h +1138 -0
- data/lua-hooks/ext/luajit/src/lj_frame.h +259 -0
- data/lua-hooks/ext/luajit/src/lj_func.c +185 -0
- data/lua-hooks/ext/luajit/src/lj_func.h +24 -0
- data/lua-hooks/ext/luajit/src/lj_func.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_func_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_gc.c +845 -0
- data/lua-hooks/ext/luajit/src/lj_gc.h +134 -0
- data/lua-hooks/ext/luajit/src/lj_gc.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_gc_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_gdbjit.c +787 -0
- data/lua-hooks/ext/luajit/src/lj_gdbjit.h +22 -0
- data/lua-hooks/ext/luajit/src/lj_gdbjit.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_gdbjit_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ir.c +505 -0
- data/lua-hooks/ext/luajit/src/lj_ir.h +577 -0
- data/lua-hooks/ext/luajit/src/lj_ir.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ir_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ircall.h +321 -0
- data/lua-hooks/ext/luajit/src/lj_iropt.h +161 -0
- data/lua-hooks/ext/luajit/src/lj_jit.h +440 -0
- data/lua-hooks/ext/luajit/src/lj_lex.c +482 -0
- data/lua-hooks/ext/luajit/src/lj_lex.h +86 -0
- data/lua-hooks/ext/luajit/src/lj_lex.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_lex_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_lib.c +303 -0
- data/lua-hooks/ext/luajit/src/lj_lib.h +115 -0
- data/lua-hooks/ext/luajit/src/lj_lib.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_lib_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_libdef.h +414 -0
- data/lua-hooks/ext/luajit/src/lj_load.c +168 -0
- data/lua-hooks/ext/luajit/src/lj_load.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_load_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_mcode.c +386 -0
- data/lua-hooks/ext/luajit/src/lj_mcode.h +30 -0
- data/lua-hooks/ext/luajit/src/lj_mcode.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_mcode_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_meta.c +477 -0
- data/lua-hooks/ext/luajit/src/lj_meta.h +38 -0
- data/lua-hooks/ext/luajit/src/lj_meta.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_meta_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_obj.c +50 -0
- data/lua-hooks/ext/luajit/src/lj_obj.h +976 -0
- data/lua-hooks/ext/luajit/src/lj_obj.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_obj_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_dce.c +78 -0
- data/lua-hooks/ext/luajit/src/lj_opt_dce.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_dce_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_fold.c +2488 -0
- data/lua-hooks/ext/luajit/src/lj_opt_fold.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_fold_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_loop.c +449 -0
- data/lua-hooks/ext/luajit/src/lj_opt_loop.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_loop_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_mem.c +935 -0
- data/lua-hooks/ext/luajit/src/lj_opt_mem.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_mem_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_narrow.c +652 -0
- data/lua-hooks/ext/luajit/src/lj_opt_narrow.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_narrow_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_sink.c +245 -0
- data/lua-hooks/ext/luajit/src/lj_opt_sink.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_sink_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_split.c +856 -0
- data/lua-hooks/ext/luajit/src/lj_opt_split.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_split_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_parse.c +2725 -0
- data/lua-hooks/ext/luajit/src/lj_parse.h +18 -0
- data/lua-hooks/ext/luajit/src/lj_parse.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_parse_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_profile.c +368 -0
- data/lua-hooks/ext/luajit/src/lj_profile.h +21 -0
- data/lua-hooks/ext/luajit/src/lj_profile.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_profile_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_recdef.h +270 -0
- data/lua-hooks/ext/luajit/src/lj_record.c +2554 -0
- data/lua-hooks/ext/luajit/src/lj_record.h +45 -0
- data/lua-hooks/ext/luajit/src/lj_record.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_record_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_snap.c +870 -0
- data/lua-hooks/ext/luajit/src/lj_snap.h +34 -0
- data/lua-hooks/ext/luajit/src/lj_snap.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_snap_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_state.c +300 -0
- data/lua-hooks/ext/luajit/src/lj_state.h +35 -0
- data/lua-hooks/ext/luajit/src/lj_state.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_state_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_str.c +197 -0
- data/lua-hooks/ext/luajit/src/lj_str.h +27 -0
- data/lua-hooks/ext/luajit/src/lj_str.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_str_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_strfmt.c +554 -0
- data/lua-hooks/ext/luajit/src/lj_strfmt.h +125 -0
- data/lua-hooks/ext/luajit/src/lj_strfmt.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_strfmt_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_strscan.c +547 -0
- data/lua-hooks/ext/luajit/src/lj_strscan.h +39 -0
- data/lua-hooks/ext/luajit/src/lj_strscan.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_strscan_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_tab.c +666 -0
- data/lua-hooks/ext/luajit/src/lj_tab.h +73 -0
- data/lua-hooks/ext/luajit/src/lj_tab.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_tab_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_target.h +164 -0
- data/lua-hooks/ext/luajit/src/lj_target_arm.h +270 -0
- data/lua-hooks/ext/luajit/src/lj_target_arm64.h +97 -0
- data/lua-hooks/ext/luajit/src/lj_target_mips.h +260 -0
- data/lua-hooks/ext/luajit/src/lj_target_ppc.h +280 -0
- data/lua-hooks/ext/luajit/src/lj_target_x86.h +345 -0
- data/lua-hooks/ext/luajit/src/lj_trace.c +859 -0
- data/lua-hooks/ext/luajit/src/lj_trace.h +54 -0
- data/lua-hooks/ext/luajit/src/lj_trace.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_trace_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_traceerr.h +63 -0
- data/lua-hooks/ext/luajit/src/lj_udata.c +34 -0
- data/lua-hooks/ext/luajit/src/lj_udata.h +14 -0
- data/lua-hooks/ext/luajit/src/lj_udata.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_udata_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vm.S +2730 -0
- data/lua-hooks/ext/luajit/src/lj_vm.h +114 -0
- data/lua-hooks/ext/luajit/src/lj_vm.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vm_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vmevent.c +58 -0
- data/lua-hooks/ext/luajit/src/lj_vmevent.h +59 -0
- data/lua-hooks/ext/luajit/src/lj_vmevent.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vmevent_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vmmath.c +152 -0
- data/lua-hooks/ext/luajit/src/lj_vmmath.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vmmath_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/ljamalg.c +96 -0
- data/lua-hooks/ext/{lua → luajit/src}/lua.h +12 -7
- data/lua-hooks/ext/luajit/src/lua.hpp +9 -0
- data/lua-hooks/ext/luajit/src/luaconf.h +156 -0
- data/lua-hooks/ext/luajit/src/luajit +0 -0
- data/lua-hooks/ext/luajit/src/luajit.c +570 -0
- data/lua-hooks/ext/luajit/src/luajit.h +79 -0
- data/lua-hooks/ext/luajit/src/luajit.o +0 -0
- data/lua-hooks/ext/luajit/src/lualib.h +43 -0
- data/lua-hooks/ext/luajit/src/msvcbuild.bat +114 -0
- data/lua-hooks/ext/luajit/src/ps4build.bat +103 -0
- data/lua-hooks/ext/luajit/src/psvitabuild.bat +93 -0
- data/lua-hooks/ext/luajit/src/vm_arm.dasc +4585 -0
- data/lua-hooks/ext/luajit/src/vm_arm64.dasc +3764 -0
- data/lua-hooks/ext/luajit/src/vm_mips.dasc +4355 -0
- data/lua-hooks/ext/luajit/src/vm_ppc.dasc +5252 -0
- data/lua-hooks/ext/luajit/src/vm_x64.dasc +4902 -0
- data/lua-hooks/ext/luajit/src/vm_x86.dasc +5710 -0
- data/lua-hooks/ext/luajit/src/xb1build.bat +101 -0
- data/lua-hooks/ext/luajit/src/xedkbuild.bat +92 -0
- data/lua-hooks/ext/luautf8/lutf8lib.c +3 -3
- data/lua-hooks/lib/boot.lua +37 -2
- metadata +372 -69
- data/lua-hooks/ext/bitop/README +0 -22
- data/lua-hooks/ext/bitop/bit.c +0 -189
- data/lua-hooks/ext/extconf.rb +0 -38
- data/lua-hooks/ext/lua/COPYRIGHT +0 -34
- data/lua-hooks/ext/lua/lapi.c +0 -1087
- data/lua-hooks/ext/lua/lapi.h +0 -16
- data/lua-hooks/ext/lua/lauxlib.c +0 -652
- data/lua-hooks/ext/lua/lbaselib.c +0 -659
- data/lua-hooks/ext/lua/lcode.c +0 -831
- data/lua-hooks/ext/lua/lcode.h +0 -76
- data/lua-hooks/ext/lua/ldblib.c +0 -398
- data/lua-hooks/ext/lua/ldebug.c +0 -638
- data/lua-hooks/ext/lua/ldebug.h +0 -33
- data/lua-hooks/ext/lua/ldo.c +0 -519
- data/lua-hooks/ext/lua/ldo.h +0 -57
- data/lua-hooks/ext/lua/ldump.c +0 -164
- data/lua-hooks/ext/lua/lfunc.c +0 -174
- data/lua-hooks/ext/lua/lfunc.h +0 -34
- data/lua-hooks/ext/lua/lgc.c +0 -710
- data/lua-hooks/ext/lua/lgc.h +0 -110
- data/lua-hooks/ext/lua/linit.c +0 -38
- data/lua-hooks/ext/lua/liolib.c +0 -556
- data/lua-hooks/ext/lua/llex.c +0 -463
- data/lua-hooks/ext/lua/llex.h +0 -81
- data/lua-hooks/ext/lua/llimits.h +0 -128
- data/lua-hooks/ext/lua/lmathlib.c +0 -263
- data/lua-hooks/ext/lua/lmem.c +0 -86
- data/lua-hooks/ext/lua/lmem.h +0 -49
- data/lua-hooks/ext/lua/loadlib.c +0 -705
- data/lua-hooks/ext/lua/loadlib_rel.c +0 -760
- data/lua-hooks/ext/lua/lobject.c +0 -214
- data/lua-hooks/ext/lua/lobject.h +0 -381
- data/lua-hooks/ext/lua/lopcodes.c +0 -102
- data/lua-hooks/ext/lua/lopcodes.h +0 -268
- data/lua-hooks/ext/lua/loslib.c +0 -243
- data/lua-hooks/ext/lua/lparser.c +0 -1339
- data/lua-hooks/ext/lua/lparser.h +0 -82
- data/lua-hooks/ext/lua/lstate.c +0 -214
- data/lua-hooks/ext/lua/lstate.h +0 -169
- data/lua-hooks/ext/lua/lstring.c +0 -111
- data/lua-hooks/ext/lua/lstring.h +0 -31
- data/lua-hooks/ext/lua/lstrlib.c +0 -871
- data/lua-hooks/ext/lua/ltable.c +0 -588
- data/lua-hooks/ext/lua/ltable.h +0 -40
- data/lua-hooks/ext/lua/ltablib.c +0 -287
- data/lua-hooks/ext/lua/ltm.c +0 -75
- data/lua-hooks/ext/lua/ltm.h +0 -54
- data/lua-hooks/ext/lua/lua.c +0 -392
- data/lua-hooks/ext/lua/lua.def +0 -131
- data/lua-hooks/ext/lua/lua.rc +0 -28
- data/lua-hooks/ext/lua/lua_dll.rc +0 -26
- data/lua-hooks/ext/lua/luac.c +0 -200
- data/lua-hooks/ext/lua/luac.rc +0 -1
- data/lua-hooks/ext/lua/luaconf.h +0 -763
- data/lua-hooks/ext/lua/luaconf.h.in +0 -724
- data/lua-hooks/ext/lua/luaconf.h.orig +0 -763
- data/lua-hooks/ext/lua/lualib.h +0 -53
- data/lua-hooks/ext/lua/lundump.c +0 -227
- data/lua-hooks/ext/lua/lundump.h +0 -36
- data/lua-hooks/ext/lua/lvm.c +0 -767
- data/lua-hooks/ext/lua/lvm.h +0 -36
- data/lua-hooks/ext/lua/lzio.c +0 -82
- data/lua-hooks/ext/lua/lzio.h +0 -67
- data/lua-hooks/ext/lua/print.c +0 -227
@@ -0,0 +1,345 @@
|
|
1
|
+
/*
|
2
|
+
** Definitions for x86 and x64 CPUs.
|
3
|
+
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef _LJ_TARGET_X86_H
|
7
|
+
#define _LJ_TARGET_X86_H
|
8
|
+
|
9
|
+
/* -- Registers IDs ------------------------------------------------------- */
|
10
|
+
|
11
|
+
#if LJ_64
|
12
|
+
#define GPRDEF(_) \
|
13
|
+
_(EAX) _(ECX) _(EDX) _(EBX) _(ESP) _(EBP) _(ESI) _(EDI) \
|
14
|
+
_(R8D) _(R9D) _(R10D) _(R11D) _(R12D) _(R13D) _(R14D) _(R15D)
|
15
|
+
#define FPRDEF(_) \
|
16
|
+
_(XMM0) _(XMM1) _(XMM2) _(XMM3) _(XMM4) _(XMM5) _(XMM6) _(XMM7) \
|
17
|
+
_(XMM8) _(XMM9) _(XMM10) _(XMM11) _(XMM12) _(XMM13) _(XMM14) _(XMM15)
|
18
|
+
#else
|
19
|
+
#define GPRDEF(_) \
|
20
|
+
_(EAX) _(ECX) _(EDX) _(EBX) _(ESP) _(EBP) _(ESI) _(EDI)
|
21
|
+
#define FPRDEF(_) \
|
22
|
+
_(XMM0) _(XMM1) _(XMM2) _(XMM3) _(XMM4) _(XMM5) _(XMM6) _(XMM7)
|
23
|
+
#endif
|
24
|
+
#define VRIDDEF(_) \
|
25
|
+
_(MRM)
|
26
|
+
|
27
|
+
#define RIDENUM(name) RID_##name,
|
28
|
+
|
29
|
+
enum {
|
30
|
+
GPRDEF(RIDENUM) /* General-purpose registers (GPRs). */
|
31
|
+
FPRDEF(RIDENUM) /* Floating-point registers (FPRs). */
|
32
|
+
RID_MAX,
|
33
|
+
RID_MRM = RID_MAX, /* Pseudo-id for ModRM operand. */
|
34
|
+
|
35
|
+
/* Calling conventions. */
|
36
|
+
RID_SP = RID_ESP,
|
37
|
+
RID_RET = RID_EAX,
|
38
|
+
#if LJ_64
|
39
|
+
RID_FPRET = RID_XMM0,
|
40
|
+
#else
|
41
|
+
RID_RETLO = RID_EAX,
|
42
|
+
RID_RETHI = RID_EDX,
|
43
|
+
#endif
|
44
|
+
|
45
|
+
/* These definitions must match with the *.dasc file(s): */
|
46
|
+
RID_BASE = RID_EDX, /* Interpreter BASE. */
|
47
|
+
#if LJ_64 && !LJ_ABI_WIN
|
48
|
+
RID_LPC = RID_EBX, /* Interpreter PC. */
|
49
|
+
RID_DISPATCH = RID_R14D, /* Interpreter DISPATCH table. */
|
50
|
+
#else
|
51
|
+
RID_LPC = RID_ESI, /* Interpreter PC. */
|
52
|
+
RID_DISPATCH = RID_EBX, /* Interpreter DISPATCH table. */
|
53
|
+
#endif
|
54
|
+
|
55
|
+
/* Register ranges [min, max) and number of registers. */
|
56
|
+
RID_MIN_GPR = RID_EAX,
|
57
|
+
RID_MIN_FPR = RID_XMM0,
|
58
|
+
RID_MAX_GPR = RID_MIN_FPR,
|
59
|
+
RID_MAX_FPR = RID_MAX,
|
60
|
+
RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR,
|
61
|
+
RID_NUM_FPR = RID_MAX_FPR - RID_MIN_FPR,
|
62
|
+
};
|
63
|
+
|
64
|
+
/* -- Register sets ------------------------------------------------------- */
|
65
|
+
|
66
|
+
/* Make use of all registers, except the stack pointer. */
|
67
|
+
#define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR)-RID2RSET(RID_ESP))
|
68
|
+
#define RSET_FPR (RSET_RANGE(RID_MIN_FPR, RID_MAX_FPR))
|
69
|
+
#define RSET_ALL (RSET_GPR|RSET_FPR)
|
70
|
+
#define RSET_INIT RSET_ALL
|
71
|
+
|
72
|
+
#if LJ_64
|
73
|
+
/* Note: this requires the use of FORCE_REX! */
|
74
|
+
#define RSET_GPR8 RSET_GPR
|
75
|
+
#else
|
76
|
+
#define RSET_GPR8 (RSET_RANGE(RID_EAX, RID_EBX+1))
|
77
|
+
#endif
|
78
|
+
|
79
|
+
/* ABI-specific register sets. */
|
80
|
+
#define RSET_ACD (RID2RSET(RID_EAX)|RID2RSET(RID_ECX)|RID2RSET(RID_EDX))
|
81
|
+
#if LJ_64
|
82
|
+
#if LJ_ABI_WIN
|
83
|
+
/* Windows x64 ABI. */
|
84
|
+
#define RSET_SCRATCH \
|
85
|
+
(RSET_ACD|RSET_RANGE(RID_R8D, RID_R11D+1)|RSET_RANGE(RID_XMM0, RID_XMM5+1))
|
86
|
+
#define REGARG_GPRS \
|
87
|
+
(RID_ECX|((RID_EDX|((RID_R8D|(RID_R9D<<5))<<5))<<5))
|
88
|
+
#define REGARG_NUMGPR 4
|
89
|
+
#define REGARG_NUMFPR 4
|
90
|
+
#define REGARG_FIRSTFPR RID_XMM0
|
91
|
+
#define REGARG_LASTFPR RID_XMM3
|
92
|
+
#define STACKARG_OFS (4*8)
|
93
|
+
#else
|
94
|
+
/* The rest of the civilized x64 world has a common ABI. */
|
95
|
+
#define RSET_SCRATCH \
|
96
|
+
(RSET_ACD|RSET_RANGE(RID_ESI, RID_R11D+1)|RSET_FPR)
|
97
|
+
#define REGARG_GPRS \
|
98
|
+
(RID_EDI|((RID_ESI|((RID_EDX|((RID_ECX|((RID_R8D|(RID_R9D \
|
99
|
+
<<5))<<5))<<5))<<5))<<5))
|
100
|
+
#define REGARG_NUMGPR 6
|
101
|
+
#define REGARG_NUMFPR 8
|
102
|
+
#define REGARG_FIRSTFPR RID_XMM0
|
103
|
+
#define REGARG_LASTFPR RID_XMM7
|
104
|
+
#define STACKARG_OFS 0
|
105
|
+
#endif
|
106
|
+
#else
|
107
|
+
/* Common x86 ABI. */
|
108
|
+
#define RSET_SCRATCH (RSET_ACD|RSET_FPR)
|
109
|
+
#define REGARG_GPRS (RID_ECX|(RID_EDX<<5)) /* Fastcall only. */
|
110
|
+
#define REGARG_NUMGPR 2 /* Fastcall only. */
|
111
|
+
#define REGARG_NUMFPR 0
|
112
|
+
#define STACKARG_OFS 0
|
113
|
+
#endif
|
114
|
+
|
115
|
+
#if LJ_64
|
116
|
+
/* Prefer the low 8 regs of each type to reduce REX prefixes. */
|
117
|
+
#undef rset_picktop
|
118
|
+
#define rset_picktop(rs) (lj_fls(lj_bswap(rs)) ^ 0x18)
|
119
|
+
#endif
|
120
|
+
|
121
|
+
/* -- Spill slots --------------------------------------------------------- */
|
122
|
+
|
123
|
+
/* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
|
124
|
+
**
|
125
|
+
** SPS_FIXED: Available fixed spill slots in interpreter frame.
|
126
|
+
** This definition must match with the *.dasc file(s).
|
127
|
+
**
|
128
|
+
** SPS_FIRST: First spill slot for general use. Reserve min. two 32 bit slots.
|
129
|
+
*/
|
130
|
+
#if LJ_64
|
131
|
+
#if LJ_ABI_WIN
|
132
|
+
#define SPS_FIXED (4*2)
|
133
|
+
#define SPS_FIRST (4*2) /* Don't use callee register save area. */
|
134
|
+
#else
|
135
|
+
#if LJ_GC64
|
136
|
+
#define SPS_FIXED 2
|
137
|
+
#else
|
138
|
+
#define SPS_FIXED 4
|
139
|
+
#endif
|
140
|
+
#define SPS_FIRST 2
|
141
|
+
#endif
|
142
|
+
#else
|
143
|
+
#define SPS_FIXED 6
|
144
|
+
#define SPS_FIRST 2
|
145
|
+
#endif
|
146
|
+
|
147
|
+
#define SPOFS_TMP 0
|
148
|
+
|
149
|
+
#define sps_scale(slot) (4 * (int32_t)(slot))
|
150
|
+
#define sps_align(slot) (((slot) - SPS_FIXED + 3) & ~3)
|
151
|
+
|
152
|
+
/* -- Exit state ---------------------------------------------------------- */
|
153
|
+
|
154
|
+
/* This definition must match with the *.dasc file(s). */
|
155
|
+
typedef struct {
|
156
|
+
lua_Number fpr[RID_NUM_FPR]; /* Floating-point registers. */
|
157
|
+
intptr_t gpr[RID_NUM_GPR]; /* General-purpose registers. */
|
158
|
+
int32_t spill[256]; /* Spill slots. */
|
159
|
+
} ExitState;
|
160
|
+
|
161
|
+
/* Limited by the range of a short fwd jump (127): (2+2)*(32-1)-2 = 122. */
|
162
|
+
#define EXITSTUB_SPACING (2+2)
|
163
|
+
#define EXITSTUBS_PER_GROUP 32
|
164
|
+
|
165
|
+
/* -- x86 ModRM operand encoding ------------------------------------------ */
|
166
|
+
|
167
|
+
typedef enum {
|
168
|
+
XM_OFS0 = 0x00, XM_OFS8 = 0x40, XM_OFS32 = 0x80, XM_REG = 0xc0,
|
169
|
+
XM_SCALE1 = 0x00, XM_SCALE2 = 0x40, XM_SCALE4 = 0x80, XM_SCALE8 = 0xc0,
|
170
|
+
XM_MASK = 0xc0
|
171
|
+
} x86Mode;
|
172
|
+
|
173
|
+
/* Structure to hold variable ModRM operand. */
|
174
|
+
typedef struct {
|
175
|
+
int32_t ofs; /* Offset. */
|
176
|
+
uint8_t base; /* Base register or RID_NONE. */
|
177
|
+
uint8_t idx; /* Index register or RID_NONE. */
|
178
|
+
uint8_t scale; /* Index scale (XM_SCALE1 .. XM_SCALE8). */
|
179
|
+
} x86ModRM;
|
180
|
+
|
181
|
+
/* -- Opcodes ------------------------------------------------------------- */
|
182
|
+
|
183
|
+
/* Macros to construct variable-length x86 opcodes. -(len+1) is in LSB. */
|
184
|
+
#define XO_(o) ((uint32_t)(0x0000fe + (0x##o<<24)))
|
185
|
+
#define XO_FPU(a,b) ((uint32_t)(0x00fd + (0x##a<<16)+(0x##b<<24)))
|
186
|
+
#define XO_0f(o) ((uint32_t)(0x0f00fd + (0x##o<<24)))
|
187
|
+
#define XO_66(o) ((uint32_t)(0x6600fd + (0x##o<<24)))
|
188
|
+
#define XO_660f(o) ((uint32_t)(0x0f66fc + (0x##o<<24)))
|
189
|
+
#define XO_f20f(o) ((uint32_t)(0x0ff2fc + (0x##o<<24)))
|
190
|
+
#define XO_f30f(o) ((uint32_t)(0x0ff3fc + (0x##o<<24)))
|
191
|
+
|
192
|
+
/* This list of x86 opcodes is not intended to be complete. Opcodes are only
|
193
|
+
** included when needed. Take a look at DynASM or jit.dis_x86 to see the
|
194
|
+
** whole mess.
|
195
|
+
*/
|
196
|
+
typedef enum {
|
197
|
+
/* Fixed length opcodes. XI_* prefix. */
|
198
|
+
XI_NOP = 0x90,
|
199
|
+
XI_XCHGa = 0x90,
|
200
|
+
XI_CALL = 0xe8,
|
201
|
+
XI_JMP = 0xe9,
|
202
|
+
XI_JMPs = 0xeb,
|
203
|
+
XI_PUSH = 0x50, /* Really 50+r. */
|
204
|
+
XI_JCCs = 0x70, /* Really 7x. */
|
205
|
+
XI_JCCn = 0x80, /* Really 0f8x. */
|
206
|
+
XI_LEA = 0x8d,
|
207
|
+
XI_MOVrib = 0xb0, /* Really b0+r. */
|
208
|
+
XI_MOVri = 0xb8, /* Really b8+r. */
|
209
|
+
XI_ARITHib = 0x80,
|
210
|
+
XI_ARITHi = 0x81,
|
211
|
+
XI_ARITHi8 = 0x83,
|
212
|
+
XI_PUSHi8 = 0x6a,
|
213
|
+
XI_TESTb = 0x84,
|
214
|
+
XI_TEST = 0x85,
|
215
|
+
XI_MOVmi = 0xc7,
|
216
|
+
XI_GROUP5 = 0xff,
|
217
|
+
|
218
|
+
/* Note: little-endian byte-order! */
|
219
|
+
XI_FLDZ = 0xeed9,
|
220
|
+
XI_FLD1 = 0xe8d9,
|
221
|
+
XI_FLDLG2 = 0xecd9,
|
222
|
+
XI_FLDLN2 = 0xedd9,
|
223
|
+
XI_FDUP = 0xc0d9, /* Really fld st0. */
|
224
|
+
XI_FPOP = 0xd8dd, /* Really fstp st0. */
|
225
|
+
XI_FPOP1 = 0xd9dd, /* Really fstp st1. */
|
226
|
+
XI_FRNDINT = 0xfcd9,
|
227
|
+
XI_FSIN = 0xfed9,
|
228
|
+
XI_FCOS = 0xffd9,
|
229
|
+
XI_FPTAN = 0xf2d9,
|
230
|
+
XI_FPATAN = 0xf3d9,
|
231
|
+
XI_FSCALE = 0xfdd9,
|
232
|
+
XI_FYL2X = 0xf1d9,
|
233
|
+
|
234
|
+
/* Variable-length opcodes. XO_* prefix. */
|
235
|
+
XO_MOV = XO_(8b),
|
236
|
+
XO_MOVto = XO_(89),
|
237
|
+
XO_MOVtow = XO_66(89),
|
238
|
+
XO_MOVtob = XO_(88),
|
239
|
+
XO_MOVmi = XO_(c7),
|
240
|
+
XO_MOVmib = XO_(c6),
|
241
|
+
XO_LEA = XO_(8d),
|
242
|
+
XO_ARITHib = XO_(80),
|
243
|
+
XO_ARITHi = XO_(81),
|
244
|
+
XO_ARITHi8 = XO_(83),
|
245
|
+
XO_ARITHiw8 = XO_66(83),
|
246
|
+
XO_SHIFTi = XO_(c1),
|
247
|
+
XO_SHIFT1 = XO_(d1),
|
248
|
+
XO_SHIFTcl = XO_(d3),
|
249
|
+
XO_IMUL = XO_0f(af),
|
250
|
+
XO_IMULi = XO_(69),
|
251
|
+
XO_IMULi8 = XO_(6b),
|
252
|
+
XO_CMP = XO_(3b),
|
253
|
+
XO_TESTb = XO_(84),
|
254
|
+
XO_TEST = XO_(85),
|
255
|
+
XO_GROUP3b = XO_(f6),
|
256
|
+
XO_GROUP3 = XO_(f7),
|
257
|
+
XO_GROUP5b = XO_(fe),
|
258
|
+
XO_GROUP5 = XO_(ff),
|
259
|
+
XO_MOVZXb = XO_0f(b6),
|
260
|
+
XO_MOVZXw = XO_0f(b7),
|
261
|
+
XO_MOVSXb = XO_0f(be),
|
262
|
+
XO_MOVSXw = XO_0f(bf),
|
263
|
+
XO_MOVSXd = XO_(63),
|
264
|
+
XO_BSWAP = XO_0f(c8),
|
265
|
+
XO_CMOV = XO_0f(40),
|
266
|
+
|
267
|
+
XO_MOVSD = XO_f20f(10),
|
268
|
+
XO_MOVSDto = XO_f20f(11),
|
269
|
+
XO_MOVSS = XO_f30f(10),
|
270
|
+
XO_MOVSSto = XO_f30f(11),
|
271
|
+
XO_MOVLPD = XO_660f(12),
|
272
|
+
XO_MOVAPS = XO_0f(28),
|
273
|
+
XO_XORPS = XO_0f(57),
|
274
|
+
XO_ANDPS = XO_0f(54),
|
275
|
+
XO_ADDSD = XO_f20f(58),
|
276
|
+
XO_SUBSD = XO_f20f(5c),
|
277
|
+
XO_MULSD = XO_f20f(59),
|
278
|
+
XO_DIVSD = XO_f20f(5e),
|
279
|
+
XO_SQRTSD = XO_f20f(51),
|
280
|
+
XO_MINSD = XO_f20f(5d),
|
281
|
+
XO_MAXSD = XO_f20f(5f),
|
282
|
+
XO_ROUNDSD = 0x0b3a0ffc, /* Really 66 0f 3a 0b. See asm_fpmath. */
|
283
|
+
XO_UCOMISD = XO_660f(2e),
|
284
|
+
XO_CVTSI2SD = XO_f20f(2a),
|
285
|
+
XO_CVTTSD2SI= XO_f20f(2c),
|
286
|
+
XO_CVTSI2SS = XO_f30f(2a),
|
287
|
+
XO_CVTTSS2SI= XO_f30f(2c),
|
288
|
+
XO_CVTSS2SD = XO_f30f(5a),
|
289
|
+
XO_CVTSD2SS = XO_f20f(5a),
|
290
|
+
XO_ADDSS = XO_f30f(58),
|
291
|
+
XO_MOVD = XO_660f(6e),
|
292
|
+
XO_MOVDto = XO_660f(7e),
|
293
|
+
|
294
|
+
XO_FLDd = XO_(d9), XOg_FLDd = 0,
|
295
|
+
XO_FLDq = XO_(dd), XOg_FLDq = 0,
|
296
|
+
XO_FILDd = XO_(db), XOg_FILDd = 0,
|
297
|
+
XO_FILDq = XO_(df), XOg_FILDq = 5,
|
298
|
+
XO_FSTPd = XO_(d9), XOg_FSTPd = 3,
|
299
|
+
XO_FSTPq = XO_(dd), XOg_FSTPq = 3,
|
300
|
+
XO_FISTPq = XO_(df), XOg_FISTPq = 7,
|
301
|
+
XO_FISTTPq = XO_(dd), XOg_FISTTPq = 1,
|
302
|
+
XO_FADDq = XO_(dc), XOg_FADDq = 0,
|
303
|
+
XO_FLDCW = XO_(d9), XOg_FLDCW = 5,
|
304
|
+
XO_FNSTCW = XO_(d9), XOg_FNSTCW = 7
|
305
|
+
} x86Op;
|
306
|
+
|
307
|
+
/* x86 opcode groups. */
|
308
|
+
typedef uint32_t x86Group;
|
309
|
+
|
310
|
+
#define XG_(i8, i, g) ((x86Group)(((i8) << 16) + ((i) << 8) + (g)))
|
311
|
+
#define XG_ARITHi(g) XG_(XI_ARITHi8, XI_ARITHi, g)
|
312
|
+
#define XG_TOXOi(xg) ((x86Op)(0x000000fe + (((xg)<<16) & 0xff000000)))
|
313
|
+
#define XG_TOXOi8(xg) ((x86Op)(0x000000fe + (((xg)<<8) & 0xff000000)))
|
314
|
+
|
315
|
+
#define XO_ARITH(a) ((x86Op)(0x030000fe + ((a)<<27)))
|
316
|
+
#define XO_ARITHw(a) ((x86Op)(0x036600fd + ((a)<<27)))
|
317
|
+
|
318
|
+
typedef enum {
|
319
|
+
XOg_ADD, XOg_OR, XOg_ADC, XOg_SBB, XOg_AND, XOg_SUB, XOg_XOR, XOg_CMP,
|
320
|
+
XOg_X_IMUL
|
321
|
+
} x86Arith;
|
322
|
+
|
323
|
+
typedef enum {
|
324
|
+
XOg_ROL, XOg_ROR, XOg_RCL, XOg_RCR, XOg_SHL, XOg_SHR, XOg_SAL, XOg_SAR
|
325
|
+
} x86Shift;
|
326
|
+
|
327
|
+
typedef enum {
|
328
|
+
XOg_TEST, XOg_TEST_, XOg_NOT, XOg_NEG, XOg_MUL, XOg_IMUL, XOg_DIV, XOg_IDIV
|
329
|
+
} x86Group3;
|
330
|
+
|
331
|
+
typedef enum {
|
332
|
+
XOg_INC, XOg_DEC, XOg_CALL, XOg_CALLfar, XOg_JMP, XOg_JMPfar, XOg_PUSH
|
333
|
+
} x86Group5;
|
334
|
+
|
335
|
+
/* x86 condition codes. */
|
336
|
+
typedef enum {
|
337
|
+
CC_O, CC_NO, CC_B, CC_NB, CC_E, CC_NE, CC_BE, CC_NBE,
|
338
|
+
CC_S, CC_NS, CC_P, CC_NP, CC_L, CC_NL, CC_LE, CC_NLE,
|
339
|
+
CC_C = CC_B, CC_NAE = CC_C, CC_NC = CC_NB, CC_AE = CC_NB,
|
340
|
+
CC_Z = CC_E, CC_NZ = CC_NE, CC_NA = CC_BE, CC_A = CC_NBE,
|
341
|
+
CC_PE = CC_P, CC_PO = CC_NP, CC_NGE = CC_L, CC_GE = CC_NL,
|
342
|
+
CC_NG = CC_LE, CC_G = CC_NLE
|
343
|
+
} x86CC;
|
344
|
+
|
345
|
+
#endif
|
@@ -0,0 +1,859 @@
|
|
1
|
+
/*
|
2
|
+
** Trace management.
|
3
|
+
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
4
|
+
*/
|
5
|
+
|
6
|
+
#define lj_trace_c
|
7
|
+
#define LUA_CORE
|
8
|
+
|
9
|
+
#include "lj_obj.h"
|
10
|
+
|
11
|
+
#if LJ_HASJIT
|
12
|
+
|
13
|
+
#include "lj_gc.h"
|
14
|
+
#include "lj_err.h"
|
15
|
+
#include "lj_debug.h"
|
16
|
+
#include "lj_str.h"
|
17
|
+
#include "lj_frame.h"
|
18
|
+
#include "lj_state.h"
|
19
|
+
#include "lj_bc.h"
|
20
|
+
#include "lj_ir.h"
|
21
|
+
#include "lj_jit.h"
|
22
|
+
#include "lj_iropt.h"
|
23
|
+
#include "lj_mcode.h"
|
24
|
+
#include "lj_trace.h"
|
25
|
+
#include "lj_snap.h"
|
26
|
+
#include "lj_gdbjit.h"
|
27
|
+
#include "lj_record.h"
|
28
|
+
#include "lj_asm.h"
|
29
|
+
#include "lj_dispatch.h"
|
30
|
+
#include "lj_vm.h"
|
31
|
+
#include "lj_vmevent.h"
|
32
|
+
#include "lj_target.h"
|
33
|
+
|
34
|
+
/* -- Error handling ------------------------------------------------------ */
|
35
|
+
|
36
|
+
/* Synchronous abort with error message. */
|
37
|
+
void lj_trace_err(jit_State *J, TraceError e)
|
38
|
+
{
|
39
|
+
setnilV(&J->errinfo); /* No error info. */
|
40
|
+
setintV(J->L->top++, (int32_t)e);
|
41
|
+
lj_err_throw(J->L, LUA_ERRRUN);
|
42
|
+
}
|
43
|
+
|
44
|
+
/* Synchronous abort with error message and error info. */
|
45
|
+
void lj_trace_err_info(jit_State *J, TraceError e)
|
46
|
+
{
|
47
|
+
setintV(J->L->top++, (int32_t)e);
|
48
|
+
lj_err_throw(J->L, LUA_ERRRUN);
|
49
|
+
}
|
50
|
+
|
51
|
+
/* -- Trace management ---------------------------------------------------- */
|
52
|
+
|
53
|
+
/* The current trace is first assembled in J->cur. The variable length
|
54
|
+
** arrays point to shared, growable buffers (J->irbuf etc.). When trace
|
55
|
+
** recording ends successfully, the current trace and its data structures
|
56
|
+
** are copied to a new (compact) GCtrace object.
|
57
|
+
*/
|
58
|
+
|
59
|
+
/* Find a free trace number. */
|
60
|
+
static TraceNo trace_findfree(jit_State *J)
|
61
|
+
{
|
62
|
+
MSize osz, lim;
|
63
|
+
if (J->freetrace == 0)
|
64
|
+
J->freetrace = 1;
|
65
|
+
for (; J->freetrace < J->sizetrace; J->freetrace++)
|
66
|
+
if (traceref(J, J->freetrace) == NULL)
|
67
|
+
return J->freetrace++;
|
68
|
+
/* Need to grow trace array. */
|
69
|
+
lim = (MSize)J->param[JIT_P_maxtrace] + 1;
|
70
|
+
if (lim < 2) lim = 2; else if (lim > 65535) lim = 65535;
|
71
|
+
osz = J->sizetrace;
|
72
|
+
if (osz >= lim)
|
73
|
+
return 0; /* Too many traces. */
|
74
|
+
lj_mem_growvec(J->L, J->trace, J->sizetrace, lim, GCRef);
|
75
|
+
for (; osz < J->sizetrace; osz++)
|
76
|
+
setgcrefnull(J->trace[osz]);
|
77
|
+
return J->freetrace;
|
78
|
+
}
|
79
|
+
|
80
|
+
#define TRACE_APPENDVEC(field, szfield, tp) \
|
81
|
+
T->field = (tp *)p; \
|
82
|
+
memcpy(p, J->cur.field, J->cur.szfield*sizeof(tp)); \
|
83
|
+
p += J->cur.szfield*sizeof(tp);
|
84
|
+
|
85
|
+
#ifdef LUAJIT_USE_PERFTOOLS
|
86
|
+
/*
|
87
|
+
** Create symbol table of JIT-compiled code. For use with Linux perf tools.
|
88
|
+
** Example usage:
|
89
|
+
** perf record -f -e cycles luajit test.lua
|
90
|
+
** perf report -s symbol
|
91
|
+
** rm perf.data /tmp/perf-*.map
|
92
|
+
*/
|
93
|
+
#include <stdio.h>
|
94
|
+
#include <unistd.h>
|
95
|
+
|
96
|
+
static void perftools_addtrace(GCtrace *T)
|
97
|
+
{
|
98
|
+
static FILE *fp;
|
99
|
+
GCproto *pt = &gcref(T->startpt)->pt;
|
100
|
+
const BCIns *startpc = mref(T->startpc, const BCIns);
|
101
|
+
const char *name = proto_chunknamestr(pt);
|
102
|
+
BCLine lineno;
|
103
|
+
if (name[0] == '@' || name[0] == '=')
|
104
|
+
name++;
|
105
|
+
else
|
106
|
+
name = "(string)";
|
107
|
+
lua_assert(startpc >= proto_bc(pt) && startpc < proto_bc(pt) + pt->sizebc);
|
108
|
+
lineno = lj_debug_line(pt, proto_bcpos(pt, startpc));
|
109
|
+
if (!fp) {
|
110
|
+
char fname[40];
|
111
|
+
sprintf(fname, "/tmp/perf-%d.map", getpid());
|
112
|
+
if (!(fp = fopen(fname, "w"))) return;
|
113
|
+
setlinebuf(fp);
|
114
|
+
}
|
115
|
+
fprintf(fp, "%lx %x TRACE_%d::%s:%u\n",
|
116
|
+
(long)T->mcode, T->szmcode, T->traceno, name, lineno);
|
117
|
+
}
|
118
|
+
#endif
|
119
|
+
|
120
|
+
/* Allocate space for copy of trace. */
|
121
|
+
static GCtrace *trace_save_alloc(jit_State *J)
|
122
|
+
{
|
123
|
+
size_t sztr = ((sizeof(GCtrace)+7)&~7);
|
124
|
+
size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns);
|
125
|
+
size_t sz = sztr + szins +
|
126
|
+
J->cur.nsnap*sizeof(SnapShot) +
|
127
|
+
J->cur.nsnapmap*sizeof(SnapEntry);
|
128
|
+
return lj_mem_newt(J->L, (MSize)sz, GCtrace);
|
129
|
+
}
|
130
|
+
|
131
|
+
/* Save current trace by copying and compacting it. */
|
132
|
+
static void trace_save(jit_State *J, GCtrace *T)
|
133
|
+
{
|
134
|
+
size_t sztr = ((sizeof(GCtrace)+7)&~7);
|
135
|
+
size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns);
|
136
|
+
char *p = (char *)T + sztr;
|
137
|
+
memcpy(T, &J->cur, sizeof(GCtrace));
|
138
|
+
setgcrefr(T->nextgc, J2G(J)->gc.root);
|
139
|
+
setgcrefp(J2G(J)->gc.root, T);
|
140
|
+
newwhite(J2G(J), T);
|
141
|
+
T->gct = ~LJ_TTRACE;
|
142
|
+
T->ir = (IRIns *)p - J->cur.nk;
|
143
|
+
memcpy(p, J->cur.ir+J->cur.nk, szins);
|
144
|
+
p += szins;
|
145
|
+
TRACE_APPENDVEC(snap, nsnap, SnapShot)
|
146
|
+
TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry)
|
147
|
+
J->cur.traceno = 0;
|
148
|
+
setgcrefp(J->trace[T->traceno], T);
|
149
|
+
lj_gc_barriertrace(J2G(J), T->traceno);
|
150
|
+
lj_gdbjit_addtrace(J, T);
|
151
|
+
#ifdef LUAJIT_USE_PERFTOOLS
|
152
|
+
perftools_addtrace(T);
|
153
|
+
#endif
|
154
|
+
}
|
155
|
+
|
156
|
+
void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T)
|
157
|
+
{
|
158
|
+
jit_State *J = G2J(g);
|
159
|
+
if (T->traceno) {
|
160
|
+
lj_gdbjit_deltrace(J, T);
|
161
|
+
if (T->traceno < J->freetrace)
|
162
|
+
J->freetrace = T->traceno;
|
163
|
+
setgcrefnull(J->trace[T->traceno]);
|
164
|
+
}
|
165
|
+
lj_mem_free(g, T,
|
166
|
+
((sizeof(GCtrace)+7)&~7) + (T->nins-T->nk)*sizeof(IRIns) +
|
167
|
+
T->nsnap*sizeof(SnapShot) + T->nsnapmap*sizeof(SnapEntry));
|
168
|
+
}
|
169
|
+
|
170
|
+
/* Re-enable compiling a prototype by unpatching any modified bytecode. */
|
171
|
+
void lj_trace_reenableproto(GCproto *pt)
|
172
|
+
{
|
173
|
+
if ((pt->flags & PROTO_ILOOP)) {
|
174
|
+
BCIns *bc = proto_bc(pt);
|
175
|
+
BCPos i, sizebc = pt->sizebc;;
|
176
|
+
pt->flags &= ~PROTO_ILOOP;
|
177
|
+
if (bc_op(bc[0]) == BC_IFUNCF)
|
178
|
+
setbc_op(&bc[0], BC_FUNCF);
|
179
|
+
for (i = 1; i < sizebc; i++) {
|
180
|
+
BCOp op = bc_op(bc[i]);
|
181
|
+
if (op == BC_IFORL || op == BC_IITERL || op == BC_ILOOP)
|
182
|
+
setbc_op(&bc[i], (int)op+(int)BC_LOOP-(int)BC_ILOOP);
|
183
|
+
}
|
184
|
+
}
|
185
|
+
}
|
186
|
+
|
187
|
+
/* Unpatch the bytecode modified by a root trace. */
|
188
|
+
static void trace_unpatch(jit_State *J, GCtrace *T)
|
189
|
+
{
|
190
|
+
BCOp op = bc_op(T->startins);
|
191
|
+
BCIns *pc = mref(T->startpc, BCIns);
|
192
|
+
UNUSED(J);
|
193
|
+
if (op == BC_JMP)
|
194
|
+
return; /* No need to unpatch branches in parent traces (yet). */
|
195
|
+
switch (bc_op(*pc)) {
|
196
|
+
case BC_JFORL:
|
197
|
+
lua_assert(traceref(J, bc_d(*pc)) == T);
|
198
|
+
*pc = T->startins;
|
199
|
+
pc += bc_j(T->startins);
|
200
|
+
lua_assert(bc_op(*pc) == BC_JFORI);
|
201
|
+
setbc_op(pc, BC_FORI);
|
202
|
+
break;
|
203
|
+
case BC_JITERL:
|
204
|
+
case BC_JLOOP:
|
205
|
+
lua_assert(op == BC_ITERL || op == BC_LOOP || bc_isret(op));
|
206
|
+
*pc = T->startins;
|
207
|
+
break;
|
208
|
+
case BC_JMP:
|
209
|
+
lua_assert(op == BC_ITERL);
|
210
|
+
pc += bc_j(*pc)+2;
|
211
|
+
if (bc_op(*pc) == BC_JITERL) {
|
212
|
+
lua_assert(traceref(J, bc_d(*pc)) == T);
|
213
|
+
*pc = T->startins;
|
214
|
+
}
|
215
|
+
break;
|
216
|
+
case BC_JFUNCF:
|
217
|
+
lua_assert(op == BC_FUNCF);
|
218
|
+
*pc = T->startins;
|
219
|
+
break;
|
220
|
+
default: /* Already unpatched. */
|
221
|
+
break;
|
222
|
+
}
|
223
|
+
}
|
224
|
+
|
225
|
+
/* Flush a root trace. */
|
226
|
+
static void trace_flushroot(jit_State *J, GCtrace *T)
|
227
|
+
{
|
228
|
+
GCproto *pt = &gcref(T->startpt)->pt;
|
229
|
+
lua_assert(T->root == 0 && pt != NULL);
|
230
|
+
/* First unpatch any modified bytecode. */
|
231
|
+
trace_unpatch(J, T);
|
232
|
+
/* Unlink root trace from chain anchored in prototype. */
|
233
|
+
if (pt->trace == T->traceno) { /* Trace is first in chain. Easy. */
|
234
|
+
pt->trace = T->nextroot;
|
235
|
+
} else if (pt->trace) { /* Otherwise search in chain of root traces. */
|
236
|
+
GCtrace *T2 = traceref(J, pt->trace);
|
237
|
+
if (T2) {
|
238
|
+
for (; T2->nextroot; T2 = traceref(J, T2->nextroot))
|
239
|
+
if (T2->nextroot == T->traceno) {
|
240
|
+
T2->nextroot = T->nextroot; /* Unlink from chain. */
|
241
|
+
break;
|
242
|
+
}
|
243
|
+
}
|
244
|
+
}
|
245
|
+
}
|
246
|
+
|
247
|
+
/* Flush a trace. Only root traces are considered. */
|
248
|
+
void lj_trace_flush(jit_State *J, TraceNo traceno)
|
249
|
+
{
|
250
|
+
if (traceno > 0 && traceno < J->sizetrace) {
|
251
|
+
GCtrace *T = traceref(J, traceno);
|
252
|
+
if (T && T->root == 0)
|
253
|
+
trace_flushroot(J, T);
|
254
|
+
}
|
255
|
+
}
|
256
|
+
|
257
|
+
/* Flush all traces associated with a prototype. */
|
258
|
+
void lj_trace_flushproto(global_State *g, GCproto *pt)
|
259
|
+
{
|
260
|
+
while (pt->trace != 0)
|
261
|
+
trace_flushroot(G2J(g), traceref(G2J(g), pt->trace));
|
262
|
+
}
|
263
|
+
|
264
|
+
/* Flush all traces. */
|
265
|
+
int lj_trace_flushall(lua_State *L)
|
266
|
+
{
|
267
|
+
jit_State *J = L2J(L);
|
268
|
+
ptrdiff_t i;
|
269
|
+
if ((J2G(J)->hookmask & HOOK_GC))
|
270
|
+
return 1;
|
271
|
+
for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--) {
|
272
|
+
GCtrace *T = traceref(J, i);
|
273
|
+
if (T) {
|
274
|
+
if (T->root == 0)
|
275
|
+
trace_flushroot(J, T);
|
276
|
+
lj_gdbjit_deltrace(J, T);
|
277
|
+
T->traceno = 0;
|
278
|
+
setgcrefnull(J->trace[i]);
|
279
|
+
}
|
280
|
+
}
|
281
|
+
J->cur.traceno = 0;
|
282
|
+
J->freetrace = 0;
|
283
|
+
/* Clear penalty cache. */
|
284
|
+
memset(J->penalty, 0, sizeof(J->penalty));
|
285
|
+
/* Free the whole machine code and invalidate all exit stub groups. */
|
286
|
+
lj_mcode_free(J);
|
287
|
+
memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup));
|
288
|
+
lj_vmevent_send(L, TRACE,
|
289
|
+
setstrV(L, L->top++, lj_str_newlit(L, "flush"));
|
290
|
+
);
|
291
|
+
return 0;
|
292
|
+
}
|
293
|
+
|
294
|
+
/* Initialize JIT compiler state. */
|
295
|
+
void lj_trace_initstate(global_State *g)
|
296
|
+
{
|
297
|
+
jit_State *J = G2J(g);
|
298
|
+
TValue *tv;
|
299
|
+
/* Initialize SIMD constants. */
|
300
|
+
tv = LJ_KSIMD(J, LJ_KSIMD_ABS);
|
301
|
+
tv[0].u64 = U64x(7fffffff,ffffffff);
|
302
|
+
tv[1].u64 = U64x(7fffffff,ffffffff);
|
303
|
+
tv = LJ_KSIMD(J, LJ_KSIMD_NEG);
|
304
|
+
tv[0].u64 = U64x(80000000,00000000);
|
305
|
+
tv[1].u64 = U64x(80000000,00000000);
|
306
|
+
}
|
307
|
+
|
308
|
+
/* Free everything associated with the JIT compiler state. */
|
309
|
+
void lj_trace_freestate(global_State *g)
|
310
|
+
{
|
311
|
+
jit_State *J = G2J(g);
|
312
|
+
#ifdef LUA_USE_ASSERT
|
313
|
+
{ /* This assumes all traces have already been freed. */
|
314
|
+
ptrdiff_t i;
|
315
|
+
for (i = 1; i < (ptrdiff_t)J->sizetrace; i++)
|
316
|
+
lua_assert(i == (ptrdiff_t)J->cur.traceno || traceref(J, i) == NULL);
|
317
|
+
}
|
318
|
+
#endif
|
319
|
+
lj_mcode_free(J);
|
320
|
+
lj_ir_k64_freeall(J);
|
321
|
+
lj_mem_freevec(g, J->snapmapbuf, J->sizesnapmap, SnapEntry);
|
322
|
+
lj_mem_freevec(g, J->snapbuf, J->sizesnap, SnapShot);
|
323
|
+
lj_mem_freevec(g, J->irbuf + J->irbotlim, J->irtoplim - J->irbotlim, IRIns);
|
324
|
+
lj_mem_freevec(g, J->trace, J->sizetrace, GCRef);
|
325
|
+
}
|
326
|
+
|
327
|
+
/* -- Penalties and blacklisting ------------------------------------------ */
|
328
|
+
|
329
|
+
/* Blacklist a bytecode instruction. */
|
330
|
+
static void blacklist_pc(GCproto *pt, BCIns *pc)
|
331
|
+
{
|
332
|
+
setbc_op(pc, (int)bc_op(*pc)+(int)BC_ILOOP-(int)BC_LOOP);
|
333
|
+
pt->flags |= PROTO_ILOOP;
|
334
|
+
}
|
335
|
+
|
336
|
+
/* Penalize a bytecode instruction. */
|
337
|
+
static void penalty_pc(jit_State *J, GCproto *pt, BCIns *pc, TraceError e)
|
338
|
+
{
|
339
|
+
uint32_t i, val = PENALTY_MIN;
|
340
|
+
for (i = 0; i < PENALTY_SLOTS; i++)
|
341
|
+
if (mref(J->penalty[i].pc, const BCIns) == pc) { /* Cache slot found? */
|
342
|
+
/* First try to bump its hotcount several times. */
|
343
|
+
val = ((uint32_t)J->penalty[i].val << 1) +
|
344
|
+
LJ_PRNG_BITS(J, PENALTY_RNDBITS);
|
345
|
+
if (val > PENALTY_MAX) {
|
346
|
+
blacklist_pc(pt, pc); /* Blacklist it, if that didn't help. */
|
347
|
+
return;
|
348
|
+
}
|
349
|
+
goto setpenalty;
|
350
|
+
}
|
351
|
+
/* Assign a new penalty cache slot. */
|
352
|
+
i = J->penaltyslot;
|
353
|
+
J->penaltyslot = (J->penaltyslot + 1) & (PENALTY_SLOTS-1);
|
354
|
+
setmref(J->penalty[i].pc, pc);
|
355
|
+
setpenalty:
|
356
|
+
J->penalty[i].val = (uint16_t)val;
|
357
|
+
J->penalty[i].reason = e;
|
358
|
+
hotcount_set(J2GG(J), pc+1, val);
|
359
|
+
}
|
360
|
+
|
361
|
+
/* -- Trace compiler state machine ---------------------------------------- */
|
362
|
+
|
363
|
+
/* Start tracing. */
|
364
|
+
static void trace_start(jit_State *J)
|
365
|
+
{
|
366
|
+
lua_State *L;
|
367
|
+
TraceNo traceno;
|
368
|
+
|
369
|
+
if ((J->pt->flags & PROTO_NOJIT)) { /* JIT disabled for this proto? */
|
370
|
+
if (J->parent == 0 && J->exitno == 0) {
|
371
|
+
/* Lazy bytecode patching to disable hotcount events. */
|
372
|
+
lua_assert(bc_op(*J->pc) == BC_FORL || bc_op(*J->pc) == BC_ITERL ||
|
373
|
+
bc_op(*J->pc) == BC_LOOP || bc_op(*J->pc) == BC_FUNCF);
|
374
|
+
setbc_op(J->pc, (int)bc_op(*J->pc)+(int)BC_ILOOP-(int)BC_LOOP);
|
375
|
+
J->pt->flags |= PROTO_ILOOP;
|
376
|
+
}
|
377
|
+
J->state = LJ_TRACE_IDLE; /* Silently ignored. */
|
378
|
+
return;
|
379
|
+
}
|
380
|
+
|
381
|
+
/* Get a new trace number. */
|
382
|
+
traceno = trace_findfree(J);
|
383
|
+
if (LJ_UNLIKELY(traceno == 0)) { /* No free trace? */
|
384
|
+
lua_assert((J2G(J)->hookmask & HOOK_GC) == 0);
|
385
|
+
lj_trace_flushall(J->L);
|
386
|
+
J->state = LJ_TRACE_IDLE; /* Silently ignored. */
|
387
|
+
return;
|
388
|
+
}
|
389
|
+
setgcrefp(J->trace[traceno], &J->cur);
|
390
|
+
|
391
|
+
/* Setup enough of the current trace to be able to send the vmevent. */
|
392
|
+
memset(&J->cur, 0, sizeof(GCtrace));
|
393
|
+
J->cur.traceno = traceno;
|
394
|
+
J->cur.nins = J->cur.nk = REF_BASE;
|
395
|
+
J->cur.ir = J->irbuf;
|
396
|
+
J->cur.snap = J->snapbuf;
|
397
|
+
J->cur.snapmap = J->snapmapbuf;
|
398
|
+
J->mergesnap = 0;
|
399
|
+
J->needsnap = 0;
|
400
|
+
J->bcskip = 0;
|
401
|
+
J->guardemit.irt = 0;
|
402
|
+
J->postproc = LJ_POST_NONE;
|
403
|
+
lj_resetsplit(J);
|
404
|
+
J->retryrec = 0;
|
405
|
+
setgcref(J->cur.startpt, obj2gco(J->pt));
|
406
|
+
|
407
|
+
L = J->L;
|
408
|
+
lj_vmevent_send(L, TRACE,
|
409
|
+
setstrV(L, L->top++, lj_str_newlit(L, "start"));
|
410
|
+
setintV(L->top++, traceno);
|
411
|
+
setfuncV(L, L->top++, J->fn);
|
412
|
+
setintV(L->top++, proto_bcpos(J->pt, J->pc));
|
413
|
+
if (J->parent) {
|
414
|
+
setintV(L->top++, J->parent);
|
415
|
+
setintV(L->top++, J->exitno);
|
416
|
+
}
|
417
|
+
);
|
418
|
+
lj_record_setup(J);
|
419
|
+
}
|
420
|
+
|
421
|
+
/* Stop tracing. */
|
422
|
+
static void trace_stop(jit_State *J)
|
423
|
+
{
|
424
|
+
BCIns *pc = mref(J->cur.startpc, BCIns);
|
425
|
+
BCOp op = bc_op(J->cur.startins);
|
426
|
+
GCproto *pt = &gcref(J->cur.startpt)->pt;
|
427
|
+
TraceNo traceno = J->cur.traceno;
|
428
|
+
GCtrace *T = trace_save_alloc(J); /* Do this first. May throw OOM. */
|
429
|
+
lua_State *L;
|
430
|
+
|
431
|
+
switch (op) {
|
432
|
+
case BC_FORL:
|
433
|
+
setbc_op(pc+bc_j(J->cur.startins), BC_JFORI); /* Patch FORI, too. */
|
434
|
+
/* fallthrough */
|
435
|
+
case BC_LOOP:
|
436
|
+
case BC_ITERL:
|
437
|
+
case BC_FUNCF:
|
438
|
+
/* Patch bytecode of starting instruction in root trace. */
|
439
|
+
setbc_op(pc, (int)op+(int)BC_JLOOP-(int)BC_LOOP);
|
440
|
+
setbc_d(pc, traceno);
|
441
|
+
addroot:
|
442
|
+
/* Add to root trace chain in prototype. */
|
443
|
+
J->cur.nextroot = pt->trace;
|
444
|
+
pt->trace = (TraceNo1)traceno;
|
445
|
+
break;
|
446
|
+
case BC_RET:
|
447
|
+
case BC_RET0:
|
448
|
+
case BC_RET1:
|
449
|
+
*pc = BCINS_AD(BC_JLOOP, J->cur.snap[0].nslots, traceno);
|
450
|
+
goto addroot;
|
451
|
+
case BC_JMP:
|
452
|
+
/* Patch exit branch in parent to side trace entry. */
|
453
|
+
lua_assert(J->parent != 0 && J->cur.root != 0);
|
454
|
+
lj_asm_patchexit(J, traceref(J, J->parent), J->exitno, J->cur.mcode);
|
455
|
+
/* Avoid compiling a side trace twice (stack resizing uses parent exit). */
|
456
|
+
traceref(J, J->parent)->snap[J->exitno].count = SNAPCOUNT_DONE;
|
457
|
+
/* Add to side trace chain in root trace. */
|
458
|
+
{
|
459
|
+
GCtrace *root = traceref(J, J->cur.root);
|
460
|
+
root->nchild++;
|
461
|
+
J->cur.nextside = root->nextside;
|
462
|
+
root->nextside = (TraceNo1)traceno;
|
463
|
+
}
|
464
|
+
break;
|
465
|
+
case BC_CALLM:
|
466
|
+
case BC_CALL:
|
467
|
+
case BC_ITERC:
|
468
|
+
/* Trace stitching: patch link of previous trace. */
|
469
|
+
traceref(J, J->exitno)->link = traceno;
|
470
|
+
break;
|
471
|
+
default:
|
472
|
+
lua_assert(0);
|
473
|
+
break;
|
474
|
+
}
|
475
|
+
|
476
|
+
/* Commit new mcode only after all patching is done. */
|
477
|
+
lj_mcode_commit(J, J->cur.mcode);
|
478
|
+
J->postproc = LJ_POST_NONE;
|
479
|
+
trace_save(J, T);
|
480
|
+
|
481
|
+
L = J->L;
|
482
|
+
lj_vmevent_send(L, TRACE,
|
483
|
+
setstrV(L, L->top++, lj_str_newlit(L, "stop"));
|
484
|
+
setintV(L->top++, traceno);
|
485
|
+
setfuncV(L, L->top++, J->fn);
|
486
|
+
);
|
487
|
+
}
|
488
|
+
|
489
|
+
/* Start a new root trace for down-recursion. */
|
490
|
+
static int trace_downrec(jit_State *J)
|
491
|
+
{
|
492
|
+
/* Restart recording at the return instruction. */
|
493
|
+
lua_assert(J->pt != NULL);
|
494
|
+
lua_assert(bc_isret(bc_op(*J->pc)));
|
495
|
+
if (bc_op(*J->pc) == BC_RETM)
|
496
|
+
return 0; /* NYI: down-recursion with RETM. */
|
497
|
+
J->parent = 0;
|
498
|
+
J->exitno = 0;
|
499
|
+
J->state = LJ_TRACE_RECORD;
|
500
|
+
trace_start(J);
|
501
|
+
return 1;
|
502
|
+
}
|
503
|
+
|
504
|
+
/* Abort tracing. */
|
505
|
+
static int trace_abort(jit_State *J)
|
506
|
+
{
|
507
|
+
lua_State *L = J->L;
|
508
|
+
TraceError e = LJ_TRERR_RECERR;
|
509
|
+
TraceNo traceno;
|
510
|
+
|
511
|
+
J->postproc = LJ_POST_NONE;
|
512
|
+
lj_mcode_abort(J);
|
513
|
+
if (tvisnumber(L->top-1))
|
514
|
+
e = (TraceError)numberVint(L->top-1);
|
515
|
+
if (e == LJ_TRERR_MCODELM) {
|
516
|
+
L->top--; /* Remove error object */
|
517
|
+
J->state = LJ_TRACE_ASM;
|
518
|
+
return 1; /* Retry ASM with new MCode area. */
|
519
|
+
}
|
520
|
+
/* Penalize or blacklist starting bytecode instruction. */
|
521
|
+
if (J->parent == 0 && !bc_isret(bc_op(J->cur.startins))) {
|
522
|
+
if (J->exitno == 0) {
|
523
|
+
BCIns *startpc = mref(J->cur.startpc, BCIns);
|
524
|
+
if (e == LJ_TRERR_RETRY)
|
525
|
+
hotcount_set(J2GG(J), startpc+1, 1); /* Immediate retry. */
|
526
|
+
else
|
527
|
+
penalty_pc(J, &gcref(J->cur.startpt)->pt, startpc, e);
|
528
|
+
} else {
|
529
|
+
traceref(J, J->exitno)->link = J->exitno; /* Self-link is blacklisted. */
|
530
|
+
}
|
531
|
+
}
|
532
|
+
|
533
|
+
/* Is there anything to abort? */
|
534
|
+
traceno = J->cur.traceno;
|
535
|
+
if (traceno) {
|
536
|
+
ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */
|
537
|
+
J->cur.link = 0;
|
538
|
+
J->cur.linktype = LJ_TRLINK_NONE;
|
539
|
+
lj_vmevent_send(L, TRACE,
|
540
|
+
TValue *frame;
|
541
|
+
const BCIns *pc;
|
542
|
+
GCfunc *fn;
|
543
|
+
setstrV(L, L->top++, lj_str_newlit(L, "abort"));
|
544
|
+
setintV(L->top++, traceno);
|
545
|
+
/* Find original Lua function call to generate a better error message. */
|
546
|
+
frame = J->L->base-1;
|
547
|
+
pc = J->pc;
|
548
|
+
while (!isluafunc(frame_func(frame))) {
|
549
|
+
pc = (frame_iscont(frame) ? frame_contpc(frame) : frame_pc(frame)) - 1;
|
550
|
+
frame = frame_prev(frame);
|
551
|
+
}
|
552
|
+
fn = frame_func(frame);
|
553
|
+
setfuncV(L, L->top++, fn);
|
554
|
+
setintV(L->top++, proto_bcpos(funcproto(fn), pc));
|
555
|
+
copyTV(L, L->top++, restorestack(L, errobj));
|
556
|
+
copyTV(L, L->top++, &J->errinfo);
|
557
|
+
);
|
558
|
+
/* Drop aborted trace after the vmevent (which may still access it). */
|
559
|
+
setgcrefnull(J->trace[traceno]);
|
560
|
+
if (traceno < J->freetrace)
|
561
|
+
J->freetrace = traceno;
|
562
|
+
J->cur.traceno = 0;
|
563
|
+
}
|
564
|
+
L->top--; /* Remove error object */
|
565
|
+
if (e == LJ_TRERR_DOWNREC)
|
566
|
+
return trace_downrec(J);
|
567
|
+
else if (e == LJ_TRERR_MCODEAL)
|
568
|
+
lj_trace_flushall(L);
|
569
|
+
return 0;
|
570
|
+
}
|
571
|
+
|
572
|
+
/* Perform pending re-patch of a bytecode instruction. */
|
573
|
+
static LJ_AINLINE void trace_pendpatch(jit_State *J, int force)
|
574
|
+
{
|
575
|
+
if (LJ_UNLIKELY(J->patchpc)) {
|
576
|
+
if (force || J->bcskip == 0) {
|
577
|
+
*J->patchpc = J->patchins;
|
578
|
+
J->patchpc = NULL;
|
579
|
+
} else {
|
580
|
+
J->bcskip = 0;
|
581
|
+
}
|
582
|
+
}
|
583
|
+
}
|
584
|
+
|
585
|
+
/* State machine for the trace compiler. Protected callback. */
|
586
|
+
static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud)
|
587
|
+
{
|
588
|
+
jit_State *J = (jit_State *)ud;
|
589
|
+
UNUSED(dummy);
|
590
|
+
do {
|
591
|
+
retry:
|
592
|
+
switch (J->state) {
|
593
|
+
case LJ_TRACE_START:
|
594
|
+
J->state = LJ_TRACE_RECORD; /* trace_start() may change state. */
|
595
|
+
trace_start(J);
|
596
|
+
lj_dispatch_update(J2G(J));
|
597
|
+
break;
|
598
|
+
|
599
|
+
case LJ_TRACE_RECORD:
|
600
|
+
trace_pendpatch(J, 0);
|
601
|
+
setvmstate(J2G(J), RECORD);
|
602
|
+
lj_vmevent_send_(L, RECORD,
|
603
|
+
/* Save/restore tmptv state for trace recorder. */
|
604
|
+
TValue savetv = J2G(J)->tmptv;
|
605
|
+
TValue savetv2 = J2G(J)->tmptv2;
|
606
|
+
setintV(L->top++, J->cur.traceno);
|
607
|
+
setfuncV(L, L->top++, J->fn);
|
608
|
+
setintV(L->top++, J->pt ? (int32_t)proto_bcpos(J->pt, J->pc) : -1);
|
609
|
+
setintV(L->top++, J->framedepth);
|
610
|
+
,
|
611
|
+
J2G(J)->tmptv = savetv;
|
612
|
+
J2G(J)->tmptv2 = savetv2;
|
613
|
+
);
|
614
|
+
lj_record_ins(J);
|
615
|
+
break;
|
616
|
+
|
617
|
+
case LJ_TRACE_END:
|
618
|
+
trace_pendpatch(J, 1);
|
619
|
+
J->loopref = 0;
|
620
|
+
if ((J->flags & JIT_F_OPT_LOOP) &&
|
621
|
+
J->cur.link == J->cur.traceno && J->framedepth + J->retdepth == 0) {
|
622
|
+
setvmstate(J2G(J), OPT);
|
623
|
+
lj_opt_dce(J);
|
624
|
+
if (lj_opt_loop(J)) { /* Loop optimization failed? */
|
625
|
+
J->cur.link = 0;
|
626
|
+
J->cur.linktype = LJ_TRLINK_NONE;
|
627
|
+
J->loopref = J->cur.nins;
|
628
|
+
J->state = LJ_TRACE_RECORD; /* Try to continue recording. */
|
629
|
+
break;
|
630
|
+
}
|
631
|
+
J->loopref = J->chain[IR_LOOP]; /* Needed by assembler. */
|
632
|
+
}
|
633
|
+
lj_opt_split(J);
|
634
|
+
lj_opt_sink(J);
|
635
|
+
if (!J->loopref) J->cur.snap[J->cur.nsnap-1].count = SNAPCOUNT_DONE;
|
636
|
+
J->state = LJ_TRACE_ASM;
|
637
|
+
break;
|
638
|
+
|
639
|
+
case LJ_TRACE_ASM:
|
640
|
+
setvmstate(J2G(J), ASM);
|
641
|
+
lj_asm_trace(J, &J->cur);
|
642
|
+
trace_stop(J);
|
643
|
+
setvmstate(J2G(J), INTERP);
|
644
|
+
J->state = LJ_TRACE_IDLE;
|
645
|
+
lj_dispatch_update(J2G(J));
|
646
|
+
return NULL;
|
647
|
+
|
648
|
+
default: /* Trace aborted asynchronously. */
|
649
|
+
setintV(L->top++, (int32_t)LJ_TRERR_RECERR);
|
650
|
+
/* fallthrough */
|
651
|
+
case LJ_TRACE_ERR:
|
652
|
+
trace_pendpatch(J, 1);
|
653
|
+
if (trace_abort(J))
|
654
|
+
goto retry;
|
655
|
+
setvmstate(J2G(J), INTERP);
|
656
|
+
J->state = LJ_TRACE_IDLE;
|
657
|
+
lj_dispatch_update(J2G(J));
|
658
|
+
return NULL;
|
659
|
+
}
|
660
|
+
} while (J->state > LJ_TRACE_RECORD);
|
661
|
+
return NULL;
|
662
|
+
}
|
663
|
+
|
664
|
+
/* -- Event handling ------------------------------------------------------ */
|
665
|
+
|
666
|
+
/* A bytecode instruction is about to be executed. Record it. */
|
667
|
+
void lj_trace_ins(jit_State *J, const BCIns *pc)
|
668
|
+
{
|
669
|
+
/* Note: J->L must already be set. pc is the true bytecode PC here. */
|
670
|
+
J->pc = pc;
|
671
|
+
J->fn = curr_func(J->L);
|
672
|
+
J->pt = isluafunc(J->fn) ? funcproto(J->fn) : NULL;
|
673
|
+
while (lj_vm_cpcall(J->L, NULL, (void *)J, trace_state) != 0)
|
674
|
+
J->state = LJ_TRACE_ERR;
|
675
|
+
}
|
676
|
+
|
677
|
+
/* A hotcount triggered. Start recording a root trace. */
|
678
|
+
void LJ_FASTCALL lj_trace_hot(jit_State *J, const BCIns *pc)
|
679
|
+
{
|
680
|
+
/* Note: pc is the interpreter bytecode PC here. It's offset by 1. */
|
681
|
+
ERRNO_SAVE
|
682
|
+
/* Reset hotcount. */
|
683
|
+
hotcount_set(J2GG(J), pc, J->param[JIT_P_hotloop]*HOTCOUNT_LOOP);
|
684
|
+
/* Only start a new trace if not recording or inside __gc call or vmevent. */
|
685
|
+
if (J->state == LJ_TRACE_IDLE &&
|
686
|
+
!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT))) {
|
687
|
+
J->parent = 0; /* Root trace. */
|
688
|
+
J->exitno = 0;
|
689
|
+
J->state = LJ_TRACE_START;
|
690
|
+
lj_trace_ins(J, pc-1);
|
691
|
+
}
|
692
|
+
ERRNO_RESTORE
|
693
|
+
}
|
694
|
+
|
695
|
+
/* Check for a hot side exit. If yes, start recording a side trace. */
|
696
|
+
static void trace_hotside(jit_State *J, const BCIns *pc)
|
697
|
+
{
|
698
|
+
SnapShot *snap = &traceref(J, J->parent)->snap[J->exitno];
|
699
|
+
if (!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT)) &&
|
700
|
+
isluafunc(curr_func(J->L)) &&
|
701
|
+
snap->count != SNAPCOUNT_DONE &&
|
702
|
+
++snap->count >= J->param[JIT_P_hotexit]) {
|
703
|
+
lua_assert(J->state == LJ_TRACE_IDLE);
|
704
|
+
/* J->parent is non-zero for a side trace. */
|
705
|
+
J->state = LJ_TRACE_START;
|
706
|
+
lj_trace_ins(J, pc);
|
707
|
+
}
|
708
|
+
}
|
709
|
+
|
710
|
+
/* Stitch a new trace to the previous trace. */
|
711
|
+
void LJ_FASTCALL lj_trace_stitch(jit_State *J, const BCIns *pc)
|
712
|
+
{
|
713
|
+
/* Only start a new trace if not recording or inside __gc call or vmevent. */
|
714
|
+
if (J->state == LJ_TRACE_IDLE &&
|
715
|
+
!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT))) {
|
716
|
+
J->parent = 0; /* Have to treat it like a root trace. */
|
717
|
+
/* J->exitno is set to the invoking trace. */
|
718
|
+
J->state = LJ_TRACE_START;
|
719
|
+
lj_trace_ins(J, pc);
|
720
|
+
}
|
721
|
+
}
|
722
|
+
|
723
|
+
|
724
|
+
/* Tiny struct to pass data to protected call. */
|
725
|
+
typedef struct ExitDataCP {
|
726
|
+
jit_State *J;
|
727
|
+
void *exptr; /* Pointer to exit state. */
|
728
|
+
const BCIns *pc; /* Restart interpreter at this PC. */
|
729
|
+
} ExitDataCP;
|
730
|
+
|
731
|
+
/* Need to protect lj_snap_restore because it may throw. */
|
732
|
+
static TValue *trace_exit_cp(lua_State *L, lua_CFunction dummy, void *ud)
|
733
|
+
{
|
734
|
+
ExitDataCP *exd = (ExitDataCP *)ud;
|
735
|
+
cframe_errfunc(L->cframe) = -1; /* Inherit error function. */
|
736
|
+
exd->pc = lj_snap_restore(exd->J, exd->exptr);
|
737
|
+
UNUSED(dummy);
|
738
|
+
return NULL;
|
739
|
+
}
|
740
|
+
|
741
|
+
#ifndef LUAJIT_DISABLE_VMEVENT
|
742
|
+
/* Push all registers from exit state. */
|
743
|
+
static void trace_exit_regs(lua_State *L, ExitState *ex)
|
744
|
+
{
|
745
|
+
int32_t i;
|
746
|
+
setintV(L->top++, RID_NUM_GPR);
|
747
|
+
setintV(L->top++, RID_NUM_FPR);
|
748
|
+
for (i = 0; i < RID_NUM_GPR; i++) {
|
749
|
+
if (sizeof(ex->gpr[i]) == sizeof(int32_t))
|
750
|
+
setintV(L->top++, (int32_t)ex->gpr[i]);
|
751
|
+
else
|
752
|
+
setnumV(L->top++, (lua_Number)ex->gpr[i]);
|
753
|
+
}
|
754
|
+
#if !LJ_SOFTFP
|
755
|
+
for (i = 0; i < RID_NUM_FPR; i++) {
|
756
|
+
setnumV(L->top, ex->fpr[i]);
|
757
|
+
if (LJ_UNLIKELY(tvisnan(L->top)))
|
758
|
+
setnanV(L->top);
|
759
|
+
L->top++;
|
760
|
+
}
|
761
|
+
#endif
|
762
|
+
}
|
763
|
+
#endif
|
764
|
+
|
765
|
+
#ifdef EXITSTATE_PCREG
|
766
|
+
/* Determine trace number from pc of exit instruction. */
|
767
|
+
static TraceNo trace_exit_find(jit_State *J, MCode *pc)
|
768
|
+
{
|
769
|
+
TraceNo traceno;
|
770
|
+
for (traceno = 1; traceno < J->sizetrace; traceno++) {
|
771
|
+
GCtrace *T = traceref(J, traceno);
|
772
|
+
if (T && pc >= T->mcode && pc < (MCode *)((char *)T->mcode + T->szmcode))
|
773
|
+
return traceno;
|
774
|
+
}
|
775
|
+
lua_assert(0);
|
776
|
+
return 0;
|
777
|
+
}
|
778
|
+
#endif
|
779
|
+
|
780
|
+
/* A trace exited. Restore interpreter state. */
|
781
|
+
int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
|
782
|
+
{
|
783
|
+
ERRNO_SAVE
|
784
|
+
lua_State *L = J->L;
|
785
|
+
ExitState *ex = (ExitState *)exptr;
|
786
|
+
ExitDataCP exd;
|
787
|
+
int errcode;
|
788
|
+
const BCIns *pc;
|
789
|
+
void *cf;
|
790
|
+
GCtrace *T;
|
791
|
+
#ifdef EXITSTATE_PCREG
|
792
|
+
J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]);
|
793
|
+
#endif
|
794
|
+
T = traceref(J, J->parent); UNUSED(T);
|
795
|
+
#ifdef EXITSTATE_CHECKEXIT
|
796
|
+
if (J->exitno == T->nsnap) { /* Treat stack check like a parent exit. */
|
797
|
+
lua_assert(T->root != 0);
|
798
|
+
J->exitno = T->ir[REF_BASE].op2;
|
799
|
+
J->parent = T->ir[REF_BASE].op1;
|
800
|
+
T = traceref(J, J->parent);
|
801
|
+
}
|
802
|
+
#endif
|
803
|
+
lua_assert(T != NULL && J->exitno < T->nsnap);
|
804
|
+
exd.J = J;
|
805
|
+
exd.exptr = exptr;
|
806
|
+
errcode = lj_vm_cpcall(L, NULL, &exd, trace_exit_cp);
|
807
|
+
if (errcode)
|
808
|
+
return -errcode; /* Return negated error code. */
|
809
|
+
|
810
|
+
if (!(LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)))
|
811
|
+
lj_vmevent_send(L, TEXIT,
|
812
|
+
lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK);
|
813
|
+
setintV(L->top++, J->parent);
|
814
|
+
setintV(L->top++, J->exitno);
|
815
|
+
trace_exit_regs(L, ex);
|
816
|
+
);
|
817
|
+
|
818
|
+
pc = exd.pc;
|
819
|
+
cf = cframe_raw(L->cframe);
|
820
|
+
setcframe_pc(cf, pc);
|
821
|
+
if (LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)) {
|
822
|
+
/* Just exit to interpreter. */
|
823
|
+
} else if (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize) {
|
824
|
+
if (!(G(L)->hookmask & HOOK_GC))
|
825
|
+
lj_gc_step(L); /* Exited because of GC: drive GC forward. */
|
826
|
+
} else {
|
827
|
+
trace_hotside(J, pc);
|
828
|
+
}
|
829
|
+
if (bc_op(*pc) == BC_JLOOP) {
|
830
|
+
BCIns *retpc = &traceref(J, bc_d(*pc))->startins;
|
831
|
+
if (bc_isret(bc_op(*retpc))) {
|
832
|
+
if (J->state == LJ_TRACE_RECORD) {
|
833
|
+
J->patchins = *pc;
|
834
|
+
J->patchpc = (BCIns *)pc;
|
835
|
+
*J->patchpc = *retpc;
|
836
|
+
J->bcskip = 1;
|
837
|
+
} else {
|
838
|
+
pc = retpc;
|
839
|
+
setcframe_pc(cf, pc);
|
840
|
+
}
|
841
|
+
}
|
842
|
+
}
|
843
|
+
/* Return MULTRES or 0. */
|
844
|
+
ERRNO_RESTORE
|
845
|
+
switch (bc_op(*pc)) {
|
846
|
+
case BC_CALLM: case BC_CALLMT:
|
847
|
+
return (int)((BCReg)(L->top - L->base) - bc_a(*pc) - bc_c(*pc) + LJ_FR2);
|
848
|
+
case BC_RETM:
|
849
|
+
return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc) - bc_d(*pc));
|
850
|
+
case BC_TSETM:
|
851
|
+
return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc));
|
852
|
+
default:
|
853
|
+
if (bc_op(*pc) >= BC_FUNCF)
|
854
|
+
return (int)((BCReg)(L->top - L->base) + 1);
|
855
|
+
return 0;
|
856
|
+
}
|
857
|
+
}
|
858
|
+
|
859
|
+
#endif
|