immunio 0.15.4 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,1247 @@
|
|
|
1
|
+
/*
|
|
2
|
+
** Fast function call recorder.
|
|
3
|
+
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
#define lj_ffrecord_c
|
|
7
|
+
#define LUA_CORE
|
|
8
|
+
|
|
9
|
+
#include "lj_obj.h"
|
|
10
|
+
|
|
11
|
+
#if LJ_HASJIT
|
|
12
|
+
|
|
13
|
+
#include "lj_err.h"
|
|
14
|
+
#include "lj_str.h"
|
|
15
|
+
#include "lj_tab.h"
|
|
16
|
+
#include "lj_frame.h"
|
|
17
|
+
#include "lj_bc.h"
|
|
18
|
+
#include "lj_ff.h"
|
|
19
|
+
#include "lj_ir.h"
|
|
20
|
+
#include "lj_jit.h"
|
|
21
|
+
#include "lj_ircall.h"
|
|
22
|
+
#include "lj_iropt.h"
|
|
23
|
+
#include "lj_trace.h"
|
|
24
|
+
#include "lj_record.h"
|
|
25
|
+
#include "lj_ffrecord.h"
|
|
26
|
+
#include "lj_crecord.h"
|
|
27
|
+
#include "lj_dispatch.h"
|
|
28
|
+
#include "lj_vm.h"
|
|
29
|
+
#include "lj_strscan.h"
|
|
30
|
+
#include "lj_strfmt.h"
|
|
31
|
+
|
|
32
|
+
/* Some local macros to save typing. Undef'd at the end. */
|
|
33
|
+
#define IR(ref) (&J->cur.ir[(ref)])
|
|
34
|
+
|
|
35
|
+
/* Pass IR on to next optimization in chain (FOLD). */
|
|
36
|
+
#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
|
|
37
|
+
|
|
38
|
+
/* -- Fast function recording handlers ------------------------------------ */
|
|
39
|
+
|
|
40
|
+
/* Conventions for fast function call handlers:
|
|
41
|
+
**
|
|
42
|
+
** The argument slots start at J->base[0]. All of them are guaranteed to be
|
|
43
|
+
** valid and type-specialized references. J->base[J->maxslot] is set to 0
|
|
44
|
+
** as a sentinel. The runtime argument values start at rd->argv[0].
|
|
45
|
+
**
|
|
46
|
+
** In general fast functions should check for presence of all of their
|
|
47
|
+
** arguments and for the correct argument types. Some simplifications
|
|
48
|
+
** are allowed if the interpreter throws instead. But even if recording
|
|
49
|
+
** is aborted, the generated IR must be consistent (no zero-refs).
|
|
50
|
+
**
|
|
51
|
+
** The number of results in rd->nres is set to 1. Handlers that return
|
|
52
|
+
** a different number of results need to override it. A negative value
|
|
53
|
+
** prevents return processing (e.g. for pending calls).
|
|
54
|
+
**
|
|
55
|
+
** Results need to be stored starting at J->base[0]. Return processing
|
|
56
|
+
** moves them to the right slots later.
|
|
57
|
+
**
|
|
58
|
+
** The per-ffid auxiliary data is the value of the 2nd part of the
|
|
59
|
+
** LJLIB_REC() annotation. This allows handling similar functionality
|
|
60
|
+
** in a common handler.
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
/* Type of handler to record a fast function. */
|
|
64
|
+
typedef void (LJ_FASTCALL *RecordFunc)(jit_State *J, RecordFFData *rd);
|
|
65
|
+
|
|
66
|
+
/* Get runtime value of int argument. */
|
|
67
|
+
static int32_t argv2int(jit_State *J, TValue *o)
|
|
68
|
+
{
|
|
69
|
+
if (!lj_strscan_numberobj(o))
|
|
70
|
+
lj_trace_err(J, LJ_TRERR_BADTYPE);
|
|
71
|
+
return tvisint(o) ? intV(o) : lj_num2int(numV(o));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* Get runtime value of string argument. */
|
|
75
|
+
static GCstr *argv2str(jit_State *J, TValue *o)
|
|
76
|
+
{
|
|
77
|
+
if (LJ_LIKELY(tvisstr(o))) {
|
|
78
|
+
return strV(o);
|
|
79
|
+
} else {
|
|
80
|
+
GCstr *s;
|
|
81
|
+
if (!tvisnumber(o))
|
|
82
|
+
lj_trace_err(J, LJ_TRERR_BADTYPE);
|
|
83
|
+
s = lj_strfmt_number(J->L, o);
|
|
84
|
+
setstrV(J->L, o, s);
|
|
85
|
+
return s;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* Return number of results wanted by caller. */
|
|
90
|
+
static ptrdiff_t results_wanted(jit_State *J)
|
|
91
|
+
{
|
|
92
|
+
TValue *frame = J->L->base-1;
|
|
93
|
+
if (frame_islua(frame))
|
|
94
|
+
return (ptrdiff_t)bc_b(frame_pc(frame)[-1]) - 1;
|
|
95
|
+
else
|
|
96
|
+
return -1;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
#ifdef LUAJIT_TRACE_STITCHING
|
|
100
|
+
/* This feature is disabled for now due to a design mistake. Sorry.
|
|
101
|
+
**
|
|
102
|
+
** It causes unpredictable behavior and crashes when a full trace flush
|
|
103
|
+
** happens with a stitching continuation still in the stack somewhere.
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
/* Trace stitching: add continuation below frame to start a new trace. */
|
|
107
|
+
static void recff_stitch(jit_State *J)
|
|
108
|
+
{
|
|
109
|
+
ASMFunction cont = lj_cont_stitch;
|
|
110
|
+
TraceNo traceno = J->cur.traceno;
|
|
111
|
+
lua_State *L = J->L;
|
|
112
|
+
TValue *base = L->base;
|
|
113
|
+
const BCIns *pc = frame_pc(base-1);
|
|
114
|
+
TValue *pframe = frame_prevl(base-1);
|
|
115
|
+
TRef trcont;
|
|
116
|
+
|
|
117
|
+
lua_assert(!LJ_FR2); /* TODO_FR2: handle frame shift. */
|
|
118
|
+
/* Move func + args up in Lua stack and insert continuation. */
|
|
119
|
+
memmove(&base[1], &base[-1], sizeof(TValue)*(J->maxslot+1));
|
|
120
|
+
setframe_ftsz(base+1, ((char *)(base+1) - (char *)pframe) + FRAME_CONT);
|
|
121
|
+
setcont(base, cont);
|
|
122
|
+
setframe_pc(base, pc);
|
|
123
|
+
if (LJ_DUALNUM) setintV(base-1, traceno); else base[-1].u64 = traceno;
|
|
124
|
+
L->base += 2;
|
|
125
|
+
L->top += 2;
|
|
126
|
+
|
|
127
|
+
/* Ditto for the IR. */
|
|
128
|
+
memmove(&J->base[1], &J->base[-1], sizeof(TRef)*(J->maxslot+1));
|
|
129
|
+
#if LJ_64
|
|
130
|
+
trcont = lj_ir_kptr(J, (void *)((int64_t)cont-(int64_t)lj_vm_asm_begin));
|
|
131
|
+
#else
|
|
132
|
+
trcont = lj_ir_kptr(J, (void *)cont);
|
|
133
|
+
#endif
|
|
134
|
+
J->base[0] = trcont | TREF_CONT;
|
|
135
|
+
J->base[-1] = LJ_DUALNUM ? lj_ir_kint(J,traceno) : lj_ir_knum_u64(J,traceno);
|
|
136
|
+
J->base += 2;
|
|
137
|
+
J->baseslot += 2;
|
|
138
|
+
J->framedepth++;
|
|
139
|
+
|
|
140
|
+
lj_record_stop(J, LJ_TRLINK_STITCH, 0);
|
|
141
|
+
|
|
142
|
+
/* Undo Lua stack changes. */
|
|
143
|
+
memmove(&base[-1], &base[1], sizeof(TValue)*(J->maxslot+1));
|
|
144
|
+
setframe_pc(base-1, pc);
|
|
145
|
+
L->base -= 2;
|
|
146
|
+
L->top -= 2;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/* Fallback handler for fast functions that are not recorded (yet). */
|
|
150
|
+
static void LJ_FASTCALL recff_nyi(jit_State *J, RecordFFData *rd)
|
|
151
|
+
{
|
|
152
|
+
if (J->cur.nins < (IRRef)J->param[JIT_P_minstitch] + REF_BASE) {
|
|
153
|
+
lj_trace_err_info(J, LJ_TRERR_TRACEUV);
|
|
154
|
+
} else {
|
|
155
|
+
/* Can only stitch from Lua call. */
|
|
156
|
+
if (J->framedepth && frame_islua(J->L->base-1)) {
|
|
157
|
+
BCOp op = bc_op(*frame_pc(J->L->base-1));
|
|
158
|
+
/* Stitched trace cannot start with *M op with variable # of args. */
|
|
159
|
+
if (!(op == BC_CALLM || op == BC_CALLMT ||
|
|
160
|
+
op == BC_RETM || op == BC_TSETM)) {
|
|
161
|
+
switch (J->fn->c.ffid) {
|
|
162
|
+
case FF_error:
|
|
163
|
+
case FF_debug_sethook:
|
|
164
|
+
case FF_jit_flush:
|
|
165
|
+
break; /* Don't stitch across special builtins. */
|
|
166
|
+
default:
|
|
167
|
+
recff_stitch(J); /* Use trace stitching. */
|
|
168
|
+
rd->nres = -1;
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/* Otherwise stop trace and return to interpreter. */
|
|
174
|
+
lj_record_stop(J, LJ_TRLINK_RETURN, 0);
|
|
175
|
+
rd->nres = -1;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* Fallback handler for unsupported variants of fast functions. */
|
|
180
|
+
#define recff_nyiu recff_nyi
|
|
181
|
+
|
|
182
|
+
/* Must stop the trace for classic C functions with arbitrary side-effects. */
|
|
183
|
+
#define recff_c recff_nyi
|
|
184
|
+
#else
|
|
185
|
+
/* Fallback handler for fast functions that are not recorded (yet). */
|
|
186
|
+
static void LJ_FASTCALL recff_nyi(jit_State *J, RecordFFData *rd)
|
|
187
|
+
{
|
|
188
|
+
setfuncV(J->L, &J->errinfo, J->fn);
|
|
189
|
+
lj_trace_err_info(J, LJ_TRERR_NYIFF);
|
|
190
|
+
UNUSED(rd);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/* Throw error for unsupported variant of fast function. */
|
|
194
|
+
LJ_NORET static void recff_nyiu(jit_State *J, RecordFFData *rd)
|
|
195
|
+
{
|
|
196
|
+
setfuncV(J->L, &J->errinfo, J->fn);
|
|
197
|
+
lj_trace_err_info(J, LJ_TRERR_NYIFFU);
|
|
198
|
+
UNUSED(rd);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* Must abort the trace for classic C functions with arbitrary side-effects. */
|
|
202
|
+
static void LJ_FASTCALL recff_c(jit_State *J, RecordFFData *rd)
|
|
203
|
+
{
|
|
204
|
+
setfuncV(J->L, &J->errinfo, J->fn);
|
|
205
|
+
lj_trace_err_info(J, LJ_TRERR_NYICF);
|
|
206
|
+
UNUSED(rd);
|
|
207
|
+
}
|
|
208
|
+
#endif
|
|
209
|
+
|
|
210
|
+
/* Emit BUFHDR for the global temporary buffer. */
|
|
211
|
+
static TRef recff_bufhdr(jit_State *J)
|
|
212
|
+
{
|
|
213
|
+
return emitir(IRT(IR_BUFHDR, IRT_P32),
|
|
214
|
+
lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/* -- Base library fast functions ----------------------------------------- */
|
|
218
|
+
|
|
219
|
+
static void LJ_FASTCALL recff_assert(jit_State *J, RecordFFData *rd)
|
|
220
|
+
{
|
|
221
|
+
/* Arguments already specialized. The interpreter throws for nil/false. */
|
|
222
|
+
rd->nres = J->maxslot; /* Pass through all arguments. */
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
static void LJ_FASTCALL recff_type(jit_State *J, RecordFFData *rd)
|
|
226
|
+
{
|
|
227
|
+
/* Arguments already specialized. Result is a constant string. Neat, huh? */
|
|
228
|
+
uint32_t t;
|
|
229
|
+
if (tvisnumber(&rd->argv[0]))
|
|
230
|
+
t = ~LJ_TNUMX;
|
|
231
|
+
else if (LJ_64 && !LJ_GC64 && tvislightud(&rd->argv[0]))
|
|
232
|
+
t = ~LJ_TLIGHTUD;
|
|
233
|
+
else
|
|
234
|
+
t = ~itype(&rd->argv[0]);
|
|
235
|
+
J->base[0] = lj_ir_kstr(J, strV(&J->fn->c.upvalue[t]));
|
|
236
|
+
UNUSED(rd);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
static void LJ_FASTCALL recff_getmetatable(jit_State *J, RecordFFData *rd)
|
|
240
|
+
{
|
|
241
|
+
TRef tr = J->base[0];
|
|
242
|
+
if (tr) {
|
|
243
|
+
RecordIndex ix;
|
|
244
|
+
ix.tab = tr;
|
|
245
|
+
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
|
246
|
+
if (lj_record_mm_lookup(J, &ix, MM_metatable))
|
|
247
|
+
J->base[0] = ix.mobj;
|
|
248
|
+
else
|
|
249
|
+
J->base[0] = ix.mt;
|
|
250
|
+
} /* else: Interpreter will throw. */
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
static void LJ_FASTCALL recff_setmetatable(jit_State *J, RecordFFData *rd)
|
|
254
|
+
{
|
|
255
|
+
TRef tr = J->base[0];
|
|
256
|
+
TRef mt = J->base[1];
|
|
257
|
+
if (tref_istab(tr) && (tref_istab(mt) || (mt && tref_isnil(mt)))) {
|
|
258
|
+
TRef fref, mtref;
|
|
259
|
+
RecordIndex ix;
|
|
260
|
+
ix.tab = tr;
|
|
261
|
+
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
|
262
|
+
lj_record_mm_lookup(J, &ix, MM_metatable); /* Guard for no __metatable. */
|
|
263
|
+
fref = emitir(IRT(IR_FREF, IRT_P32), tr, IRFL_TAB_META);
|
|
264
|
+
mtref = tref_isnil(mt) ? lj_ir_knull(J, IRT_TAB) : mt;
|
|
265
|
+
emitir(IRT(IR_FSTORE, IRT_TAB), fref, mtref);
|
|
266
|
+
if (!tref_isnil(mt))
|
|
267
|
+
emitir(IRT(IR_TBAR, IRT_TAB), tr, 0);
|
|
268
|
+
J->base[0] = tr;
|
|
269
|
+
J->needsnap = 1;
|
|
270
|
+
} /* else: Interpreter will throw. */
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
static void LJ_FASTCALL recff_rawget(jit_State *J, RecordFFData *rd)
|
|
274
|
+
{
|
|
275
|
+
RecordIndex ix;
|
|
276
|
+
ix.tab = J->base[0]; ix.key = J->base[1];
|
|
277
|
+
if (tref_istab(ix.tab) && ix.key) {
|
|
278
|
+
ix.val = 0; ix.idxchain = 0;
|
|
279
|
+
settabV(J->L, &ix.tabv, tabV(&rd->argv[0]));
|
|
280
|
+
copyTV(J->L, &ix.keyv, &rd->argv[1]);
|
|
281
|
+
J->base[0] = lj_record_idx(J, &ix);
|
|
282
|
+
} /* else: Interpreter will throw. */
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
static void LJ_FASTCALL recff_rawset(jit_State *J, RecordFFData *rd)
|
|
286
|
+
{
|
|
287
|
+
RecordIndex ix;
|
|
288
|
+
ix.tab = J->base[0]; ix.key = J->base[1]; ix.val = J->base[2];
|
|
289
|
+
if (tref_istab(ix.tab) && ix.key && ix.val) {
|
|
290
|
+
ix.idxchain = 0;
|
|
291
|
+
settabV(J->L, &ix.tabv, tabV(&rd->argv[0]));
|
|
292
|
+
copyTV(J->L, &ix.keyv, &rd->argv[1]);
|
|
293
|
+
copyTV(J->L, &ix.valv, &rd->argv[2]);
|
|
294
|
+
lj_record_idx(J, &ix);
|
|
295
|
+
/* Pass through table at J->base[0] as result. */
|
|
296
|
+
} /* else: Interpreter will throw. */
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
static void LJ_FASTCALL recff_rawequal(jit_State *J, RecordFFData *rd)
|
|
300
|
+
{
|
|
301
|
+
TRef tra = J->base[0];
|
|
302
|
+
TRef trb = J->base[1];
|
|
303
|
+
if (tra && trb) {
|
|
304
|
+
int diff = lj_record_objcmp(J, tra, trb, &rd->argv[0], &rd->argv[1]);
|
|
305
|
+
J->base[0] = diff ? TREF_FALSE : TREF_TRUE;
|
|
306
|
+
} /* else: Interpreter will throw. */
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
#if LJ_52
|
|
310
|
+
static void LJ_FASTCALL recff_rawlen(jit_State *J, RecordFFData *rd)
|
|
311
|
+
{
|
|
312
|
+
TRef tr = J->base[0];
|
|
313
|
+
if (tref_isstr(tr))
|
|
314
|
+
J->base[0] = emitir(IRTI(IR_FLOAD), tr, IRFL_STR_LEN);
|
|
315
|
+
else if (tref_istab(tr))
|
|
316
|
+
J->base[0] = lj_ir_call(J, IRCALL_lj_tab_len, tr);
|
|
317
|
+
/* else: Interpreter will throw. */
|
|
318
|
+
UNUSED(rd);
|
|
319
|
+
}
|
|
320
|
+
#endif
|
|
321
|
+
|
|
322
|
+
/* Determine mode of select() call. */
|
|
323
|
+
int32_t lj_ffrecord_select_mode(jit_State *J, TRef tr, TValue *tv)
|
|
324
|
+
{
|
|
325
|
+
if (tref_isstr(tr) && *strVdata(tv) == '#') { /* select('#', ...) */
|
|
326
|
+
if (strV(tv)->len == 1) {
|
|
327
|
+
emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, strV(tv)));
|
|
328
|
+
} else {
|
|
329
|
+
TRef trptr = emitir(IRT(IR_STRREF, IRT_P32), tr, lj_ir_kint(J, 0));
|
|
330
|
+
TRef trchar = emitir(IRT(IR_XLOAD, IRT_U8), trptr, IRXLOAD_READONLY);
|
|
331
|
+
emitir(IRTG(IR_EQ, IRT_INT), trchar, lj_ir_kint(J, '#'));
|
|
332
|
+
}
|
|
333
|
+
return 0;
|
|
334
|
+
} else { /* select(n, ...) */
|
|
335
|
+
int32_t start = argv2int(J, tv);
|
|
336
|
+
if (start == 0) lj_trace_err(J, LJ_TRERR_BADTYPE); /* A bit misleading. */
|
|
337
|
+
return start;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
static void LJ_FASTCALL recff_select(jit_State *J, RecordFFData *rd)
|
|
342
|
+
{
|
|
343
|
+
TRef tr = J->base[0];
|
|
344
|
+
if (tr) {
|
|
345
|
+
ptrdiff_t start = lj_ffrecord_select_mode(J, tr, &rd->argv[0]);
|
|
346
|
+
if (start == 0) { /* select('#', ...) */
|
|
347
|
+
J->base[0] = lj_ir_kint(J, J->maxslot - 1);
|
|
348
|
+
} else if (tref_isk(tr)) { /* select(k, ...) */
|
|
349
|
+
ptrdiff_t n = (ptrdiff_t)J->maxslot;
|
|
350
|
+
if (start < 0) start += n;
|
|
351
|
+
else if (start > n) start = n;
|
|
352
|
+
rd->nres = n - start;
|
|
353
|
+
if (start >= 1) {
|
|
354
|
+
ptrdiff_t i;
|
|
355
|
+
for (i = 0; i < n - start; i++)
|
|
356
|
+
J->base[i] = J->base[start+i];
|
|
357
|
+
} /* else: Interpreter will throw. */
|
|
358
|
+
} else {
|
|
359
|
+
recff_nyiu(J, rd);
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
} /* else: Interpreter will throw. */
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
static void LJ_FASTCALL recff_tonumber(jit_State *J, RecordFFData *rd)
|
|
366
|
+
{
|
|
367
|
+
TRef tr = J->base[0];
|
|
368
|
+
TRef base = J->base[1];
|
|
369
|
+
if (tr && !tref_isnil(base)) {
|
|
370
|
+
base = lj_opt_narrow_toint(J, base);
|
|
371
|
+
if (!tref_isk(base) || IR(tref_ref(base))->i != 10) {
|
|
372
|
+
recff_nyiu(J, rd);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
if (tref_isnumber_str(tr)) {
|
|
377
|
+
if (tref_isstr(tr)) {
|
|
378
|
+
TValue tmp;
|
|
379
|
+
if (!lj_strscan_num(strV(&rd->argv[0]), &tmp)) {
|
|
380
|
+
recff_nyiu(J, rd); /* Would need an inverted STRTO for this case. */
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0);
|
|
384
|
+
}
|
|
385
|
+
#if LJ_HASFFI
|
|
386
|
+
} else if (tref_iscdata(tr)) {
|
|
387
|
+
lj_crecord_tonumber(J, rd);
|
|
388
|
+
return;
|
|
389
|
+
#endif
|
|
390
|
+
} else {
|
|
391
|
+
tr = TREF_NIL;
|
|
392
|
+
}
|
|
393
|
+
J->base[0] = tr;
|
|
394
|
+
UNUSED(rd);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
static TValue *recff_metacall_cp(lua_State *L, lua_CFunction dummy, void *ud)
|
|
398
|
+
{
|
|
399
|
+
jit_State *J = (jit_State *)ud;
|
|
400
|
+
lj_record_tailcall(J, 0, 1);
|
|
401
|
+
UNUSED(L); UNUSED(dummy);
|
|
402
|
+
return NULL;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
static int recff_metacall(jit_State *J, RecordFFData *rd, MMS mm)
|
|
406
|
+
{
|
|
407
|
+
RecordIndex ix;
|
|
408
|
+
ix.tab = J->base[0];
|
|
409
|
+
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
|
410
|
+
if (lj_record_mm_lookup(J, &ix, mm)) { /* Has metamethod? */
|
|
411
|
+
int errcode;
|
|
412
|
+
TValue argv0;
|
|
413
|
+
/* Temporarily insert metamethod below object. */
|
|
414
|
+
J->base[1] = J->base[0];
|
|
415
|
+
J->base[0] = ix.mobj;
|
|
416
|
+
copyTV(J->L, &argv0, &rd->argv[0]);
|
|
417
|
+
copyTV(J->L, &rd->argv[1], &rd->argv[0]);
|
|
418
|
+
copyTV(J->L, &rd->argv[0], &ix.mobjv);
|
|
419
|
+
/* Need to protect lj_record_tailcall because it may throw. */
|
|
420
|
+
errcode = lj_vm_cpcall(J->L, NULL, J, recff_metacall_cp);
|
|
421
|
+
/* Always undo Lua stack changes to avoid confusing the interpreter. */
|
|
422
|
+
copyTV(J->L, &rd->argv[0], &argv0);
|
|
423
|
+
if (errcode)
|
|
424
|
+
lj_err_throw(J->L, errcode); /* Propagate errors. */
|
|
425
|
+
rd->nres = -1; /* Pending call. */
|
|
426
|
+
return 1; /* Tailcalled to metamethod. */
|
|
427
|
+
}
|
|
428
|
+
return 0;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
static void LJ_FASTCALL recff_tostring(jit_State *J, RecordFFData *rd)
|
|
432
|
+
{
|
|
433
|
+
TRef tr = J->base[0];
|
|
434
|
+
if (tref_isstr(tr)) {
|
|
435
|
+
/* Ignore __tostring in the string base metatable. */
|
|
436
|
+
/* Pass on result in J->base[0]. */
|
|
437
|
+
} else if (tr && !recff_metacall(J, rd, MM_tostring)) {
|
|
438
|
+
if (tref_isnumber(tr)) {
|
|
439
|
+
J->base[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr,
|
|
440
|
+
tref_isnum(tr) ? IRTOSTR_NUM : IRTOSTR_INT);
|
|
441
|
+
} else if (tref_ispri(tr)) {
|
|
442
|
+
J->base[0] = lj_ir_kstr(J, lj_strfmt_obj(J->L, &rd->argv[0]));
|
|
443
|
+
} else {
|
|
444
|
+
recff_nyiu(J, rd);
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
static void LJ_FASTCALL recff_ipairs_aux(jit_State *J, RecordFFData *rd)
|
|
451
|
+
{
|
|
452
|
+
RecordIndex ix;
|
|
453
|
+
ix.tab = J->base[0];
|
|
454
|
+
if (tref_istab(ix.tab)) {
|
|
455
|
+
if (!tvisnumber(&rd->argv[1])) /* No support for string coercion. */
|
|
456
|
+
lj_trace_err(J, LJ_TRERR_BADTYPE);
|
|
457
|
+
setintV(&ix.keyv, numberVint(&rd->argv[1])+1);
|
|
458
|
+
settabV(J->L, &ix.tabv, tabV(&rd->argv[0]));
|
|
459
|
+
ix.val = 0; ix.idxchain = 0;
|
|
460
|
+
ix.key = lj_opt_narrow_toint(J, J->base[1]);
|
|
461
|
+
J->base[0] = ix.key = emitir(IRTI(IR_ADD), ix.key, lj_ir_kint(J, 1));
|
|
462
|
+
J->base[1] = lj_record_idx(J, &ix);
|
|
463
|
+
rd->nres = tref_isnil(J->base[1]) ? 0 : 2;
|
|
464
|
+
} /* else: Interpreter will throw. */
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
static void LJ_FASTCALL recff_xpairs(jit_State *J, RecordFFData *rd)
|
|
468
|
+
{
|
|
469
|
+
if (!(LJ_52 && recff_metacall(J, rd, MM_ipairs))) {
|
|
470
|
+
TRef tab = J->base[0];
|
|
471
|
+
if (tref_istab(tab)) {
|
|
472
|
+
J->base[0] = lj_ir_kfunc(J, funcV(&J->fn->c.upvalue[0]));
|
|
473
|
+
J->base[1] = tab;
|
|
474
|
+
J->base[2] = rd->data ? lj_ir_kint(J, 0) : TREF_NIL;
|
|
475
|
+
rd->nres = 3;
|
|
476
|
+
} /* else: Interpreter will throw. */
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
static void LJ_FASTCALL recff_pcall(jit_State *J, RecordFFData *rd)
|
|
481
|
+
{
|
|
482
|
+
if (J->maxslot >= 1) {
|
|
483
|
+
lj_record_call(J, 0, J->maxslot - 1);
|
|
484
|
+
rd->nres = -1; /* Pending call. */
|
|
485
|
+
} /* else: Interpreter will throw. */
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
static TValue *recff_xpcall_cp(lua_State *L, lua_CFunction dummy, void *ud)
|
|
489
|
+
{
|
|
490
|
+
jit_State *J = (jit_State *)ud;
|
|
491
|
+
lj_record_call(J, 1, J->maxslot - 2);
|
|
492
|
+
UNUSED(L); UNUSED(dummy);
|
|
493
|
+
return NULL;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
static void LJ_FASTCALL recff_xpcall(jit_State *J, RecordFFData *rd)
|
|
497
|
+
{
|
|
498
|
+
if (J->maxslot >= 2) {
|
|
499
|
+
TValue argv0, argv1;
|
|
500
|
+
TRef tmp;
|
|
501
|
+
int errcode;
|
|
502
|
+
lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */
|
|
503
|
+
/* Swap function and traceback. */
|
|
504
|
+
tmp = J->base[0]; J->base[0] = J->base[1]; J->base[1] = tmp;
|
|
505
|
+
copyTV(J->L, &argv0, &rd->argv[0]);
|
|
506
|
+
copyTV(J->L, &argv1, &rd->argv[1]);
|
|
507
|
+
copyTV(J->L, &rd->argv[0], &argv1);
|
|
508
|
+
copyTV(J->L, &rd->argv[1], &argv0);
|
|
509
|
+
/* Need to protect lj_record_call because it may throw. */
|
|
510
|
+
errcode = lj_vm_cpcall(J->L, NULL, J, recff_xpcall_cp);
|
|
511
|
+
/* Always undo Lua stack swap to avoid confusing the interpreter. */
|
|
512
|
+
copyTV(J->L, &rd->argv[0], &argv0);
|
|
513
|
+
copyTV(J->L, &rd->argv[1], &argv1);
|
|
514
|
+
if (errcode)
|
|
515
|
+
lj_err_throw(J->L, errcode); /* Propagate errors. */
|
|
516
|
+
rd->nres = -1; /* Pending call. */
|
|
517
|
+
} /* else: Interpreter will throw. */
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
static void LJ_FASTCALL recff_getfenv(jit_State *J, RecordFFData *rd)
|
|
521
|
+
{
|
|
522
|
+
TRef tr = J->base[0];
|
|
523
|
+
/* Only support getfenv(0) for now. */
|
|
524
|
+
if (tref_isint(tr) && tref_isk(tr) && IR(tref_ref(tr))->i == 0) {
|
|
525
|
+
TRef trl = emitir(IRT(IR_LREF, IRT_THREAD), 0, 0);
|
|
526
|
+
J->base[0] = emitir(IRT(IR_FLOAD, IRT_TAB), trl, IRFL_THREAD_ENV);
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
recff_nyiu(J, rd);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/* -- Math library fast functions ----------------------------------------- */
|
|
533
|
+
|
|
534
|
+
static void LJ_FASTCALL recff_math_abs(jit_State *J, RecordFFData *rd)
|
|
535
|
+
{
|
|
536
|
+
TRef tr = lj_ir_tonum(J, J->base[0]);
|
|
537
|
+
J->base[0] = emitir(IRTN(IR_ABS), tr, lj_ir_knum_abs(J));
|
|
538
|
+
UNUSED(rd);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/* Record rounding functions math.floor and math.ceil. */
|
|
542
|
+
static void LJ_FASTCALL recff_math_round(jit_State *J, RecordFFData *rd)
|
|
543
|
+
{
|
|
544
|
+
TRef tr = J->base[0];
|
|
545
|
+
if (!tref_isinteger(tr)) { /* Pass through integers unmodified. */
|
|
546
|
+
tr = emitir(IRTN(IR_FPMATH), lj_ir_tonum(J, tr), rd->data);
|
|
547
|
+
/* Result is integral (or NaN/Inf), but may not fit an int32_t. */
|
|
548
|
+
if (LJ_DUALNUM) { /* Try to narrow using a guarded conversion to int. */
|
|
549
|
+
lua_Number n = lj_vm_foldfpm(numberVnum(&rd->argv[0]), rd->data);
|
|
550
|
+
if (n == (lua_Number)lj_num2int(n))
|
|
551
|
+
tr = emitir(IRTGI(IR_CONV), tr, IRCONV_INT_NUM|IRCONV_CHECK);
|
|
552
|
+
}
|
|
553
|
+
J->base[0] = tr;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/* Record unary math.* functions, mapped to IR_FPMATH opcode. */
|
|
558
|
+
static void LJ_FASTCALL recff_math_unary(jit_State *J, RecordFFData *rd)
|
|
559
|
+
{
|
|
560
|
+
J->base[0] = emitir(IRTN(IR_FPMATH), lj_ir_tonum(J, J->base[0]), rd->data);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/* Record math.log. */
|
|
564
|
+
static void LJ_FASTCALL recff_math_log(jit_State *J, RecordFFData *rd)
|
|
565
|
+
{
|
|
566
|
+
TRef tr = lj_ir_tonum(J, J->base[0]);
|
|
567
|
+
if (J->base[1]) {
|
|
568
|
+
#ifdef LUAJIT_NO_LOG2
|
|
569
|
+
uint32_t fpm = IRFPM_LOG;
|
|
570
|
+
#else
|
|
571
|
+
uint32_t fpm = IRFPM_LOG2;
|
|
572
|
+
#endif
|
|
573
|
+
TRef trb = lj_ir_tonum(J, J->base[1]);
|
|
574
|
+
tr = emitir(IRTN(IR_FPMATH), tr, fpm);
|
|
575
|
+
trb = emitir(IRTN(IR_FPMATH), trb, fpm);
|
|
576
|
+
trb = emitir(IRTN(IR_DIV), lj_ir_knum_one(J), trb);
|
|
577
|
+
tr = emitir(IRTN(IR_MUL), tr, trb);
|
|
578
|
+
} else {
|
|
579
|
+
tr = emitir(IRTN(IR_FPMATH), tr, IRFPM_LOG);
|
|
580
|
+
}
|
|
581
|
+
J->base[0] = tr;
|
|
582
|
+
UNUSED(rd);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/* Record math.atan2. */
|
|
586
|
+
static void LJ_FASTCALL recff_math_atan2(jit_State *J, RecordFFData *rd)
|
|
587
|
+
{
|
|
588
|
+
TRef tr = lj_ir_tonum(J, J->base[0]);
|
|
589
|
+
TRef tr2 = lj_ir_tonum(J, J->base[1]);
|
|
590
|
+
J->base[0] = emitir(IRTN(IR_ATAN2), tr, tr2);
|
|
591
|
+
UNUSED(rd);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/* Record math.ldexp. */
|
|
595
|
+
static void LJ_FASTCALL recff_math_ldexp(jit_State *J, RecordFFData *rd)
|
|
596
|
+
{
|
|
597
|
+
TRef tr = lj_ir_tonum(J, J->base[0]);
|
|
598
|
+
#if LJ_TARGET_X86ORX64
|
|
599
|
+
TRef tr2 = lj_ir_tonum(J, J->base[1]);
|
|
600
|
+
#else
|
|
601
|
+
TRef tr2 = lj_opt_narrow_toint(J, J->base[1]);
|
|
602
|
+
#endif
|
|
603
|
+
J->base[0] = emitir(IRTN(IR_LDEXP), tr, tr2);
|
|
604
|
+
UNUSED(rd);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/* Record math.asin, math.acos, math.atan. */
|
|
608
|
+
static void LJ_FASTCALL recff_math_atrig(jit_State *J, RecordFFData *rd)
|
|
609
|
+
{
|
|
610
|
+
TRef y = lj_ir_tonum(J, J->base[0]);
|
|
611
|
+
TRef x = lj_ir_knum_one(J);
|
|
612
|
+
uint32_t ffid = rd->data;
|
|
613
|
+
if (ffid != FF_math_atan) {
|
|
614
|
+
TRef tmp = emitir(IRTN(IR_MUL), y, y);
|
|
615
|
+
tmp = emitir(IRTN(IR_SUB), x, tmp);
|
|
616
|
+
tmp = emitir(IRTN(IR_FPMATH), tmp, IRFPM_SQRT);
|
|
617
|
+
if (ffid == FF_math_asin) { x = tmp; } else { x = y; y = tmp; }
|
|
618
|
+
}
|
|
619
|
+
J->base[0] = emitir(IRTN(IR_ATAN2), y, x);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
static void LJ_FASTCALL recff_math_htrig(jit_State *J, RecordFFData *rd)
|
|
623
|
+
{
|
|
624
|
+
TRef tr = lj_ir_tonum(J, J->base[0]);
|
|
625
|
+
J->base[0] = emitir(IRTN(IR_CALLN), tr, rd->data);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
static void LJ_FASTCALL recff_math_modf(jit_State *J, RecordFFData *rd)
|
|
629
|
+
{
|
|
630
|
+
TRef tr = J->base[0];
|
|
631
|
+
if (tref_isinteger(tr)) {
|
|
632
|
+
J->base[0] = tr;
|
|
633
|
+
J->base[1] = lj_ir_kint(J, 0);
|
|
634
|
+
} else {
|
|
635
|
+
TRef trt;
|
|
636
|
+
tr = lj_ir_tonum(J, tr);
|
|
637
|
+
trt = emitir(IRTN(IR_FPMATH), tr, IRFPM_TRUNC);
|
|
638
|
+
J->base[0] = trt;
|
|
639
|
+
J->base[1] = emitir(IRTN(IR_SUB), tr, trt);
|
|
640
|
+
}
|
|
641
|
+
rd->nres = 2;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
static void LJ_FASTCALL recff_math_pow(jit_State *J, RecordFFData *rd)
|
|
645
|
+
{
|
|
646
|
+
TRef tr = lj_ir_tonum(J, J->base[0]);
|
|
647
|
+
if (!tref_isnumber_str(J->base[1]))
|
|
648
|
+
lj_trace_err(J, LJ_TRERR_BADTYPE);
|
|
649
|
+
J->base[0] = lj_opt_narrow_pow(J, tr, J->base[1], &rd->argv[1]);
|
|
650
|
+
UNUSED(rd);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
static void LJ_FASTCALL recff_math_minmax(jit_State *J, RecordFFData *rd)
|
|
654
|
+
{
|
|
655
|
+
TRef tr = lj_ir_tonumber(J, J->base[0]);
|
|
656
|
+
uint32_t op = rd->data;
|
|
657
|
+
BCReg i;
|
|
658
|
+
for (i = 1; J->base[i] != 0; i++) {
|
|
659
|
+
TRef tr2 = lj_ir_tonumber(J, J->base[i]);
|
|
660
|
+
IRType t = IRT_INT;
|
|
661
|
+
if (!(tref_isinteger(tr) && tref_isinteger(tr2))) {
|
|
662
|
+
if (tref_isinteger(tr)) tr = emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
|
|
663
|
+
if (tref_isinteger(tr2)) tr2 = emitir(IRTN(IR_CONV), tr2, IRCONV_NUM_INT);
|
|
664
|
+
t = IRT_NUM;
|
|
665
|
+
}
|
|
666
|
+
tr = emitir(IRT(op, t), tr, tr2);
|
|
667
|
+
}
|
|
668
|
+
J->base[0] = tr;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
static void LJ_FASTCALL recff_math_random(jit_State *J, RecordFFData *rd)
|
|
672
|
+
{
|
|
673
|
+
GCudata *ud = udataV(&J->fn->c.upvalue[0]);
|
|
674
|
+
TRef tr, one;
|
|
675
|
+
lj_ir_kgc(J, obj2gco(ud), IRT_UDATA); /* Prevent collection. */
|
|
676
|
+
tr = lj_ir_call(J, IRCALL_lj_math_random_step, lj_ir_kptr(J, uddata(ud)));
|
|
677
|
+
one = lj_ir_knum_one(J);
|
|
678
|
+
tr = emitir(IRTN(IR_SUB), tr, one);
|
|
679
|
+
if (J->base[0]) {
|
|
680
|
+
TRef tr1 = lj_ir_tonum(J, J->base[0]);
|
|
681
|
+
if (J->base[1]) { /* d = floor(d*(r2-r1+1.0)) + r1 */
|
|
682
|
+
TRef tr2 = lj_ir_tonum(J, J->base[1]);
|
|
683
|
+
tr2 = emitir(IRTN(IR_SUB), tr2, tr1);
|
|
684
|
+
tr2 = emitir(IRTN(IR_ADD), tr2, one);
|
|
685
|
+
tr = emitir(IRTN(IR_MUL), tr, tr2);
|
|
686
|
+
tr = emitir(IRTN(IR_FPMATH), tr, IRFPM_FLOOR);
|
|
687
|
+
tr = emitir(IRTN(IR_ADD), tr, tr1);
|
|
688
|
+
} else { /* d = floor(d*r1) + 1.0 */
|
|
689
|
+
tr = emitir(IRTN(IR_MUL), tr, tr1);
|
|
690
|
+
tr = emitir(IRTN(IR_FPMATH), tr, IRFPM_FLOOR);
|
|
691
|
+
tr = emitir(IRTN(IR_ADD), tr, one);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
J->base[0] = tr;
|
|
695
|
+
UNUSED(rd);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/* -- Bit library fast functions ------------------------------------------ */
|
|
699
|
+
|
|
700
|
+
/* Record bit.tobit. */
|
|
701
|
+
static void LJ_FASTCALL recff_bit_tobit(jit_State *J, RecordFFData *rd)
|
|
702
|
+
{
|
|
703
|
+
TRef tr = J->base[0];
|
|
704
|
+
#if LJ_HASFFI
|
|
705
|
+
if (tref_iscdata(tr)) { recff_bit64_tobit(J, rd); return; }
|
|
706
|
+
#endif
|
|
707
|
+
J->base[0] = lj_opt_narrow_tobit(J, tr);
|
|
708
|
+
UNUSED(rd);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/* Record unary bit.bnot, bit.bswap. */
|
|
712
|
+
static void LJ_FASTCALL recff_bit_unary(jit_State *J, RecordFFData *rd)
|
|
713
|
+
{
|
|
714
|
+
#if LJ_HASFFI
|
|
715
|
+
if (recff_bit64_unary(J, rd))
|
|
716
|
+
return;
|
|
717
|
+
#endif
|
|
718
|
+
J->base[0] = emitir(IRTI(rd->data), lj_opt_narrow_tobit(J, J->base[0]), 0);
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/* Record N-ary bit.band, bit.bor, bit.bxor. */
|
|
722
|
+
static void LJ_FASTCALL recff_bit_nary(jit_State *J, RecordFFData *rd)
|
|
723
|
+
{
|
|
724
|
+
#if LJ_HASFFI
|
|
725
|
+
if (recff_bit64_nary(J, rd))
|
|
726
|
+
return;
|
|
727
|
+
#endif
|
|
728
|
+
{
|
|
729
|
+
TRef tr = lj_opt_narrow_tobit(J, J->base[0]);
|
|
730
|
+
uint32_t ot = IRTI(rd->data);
|
|
731
|
+
BCReg i;
|
|
732
|
+
for (i = 1; J->base[i] != 0; i++)
|
|
733
|
+
tr = emitir(ot, tr, lj_opt_narrow_tobit(J, J->base[i]));
|
|
734
|
+
J->base[0] = tr;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/* Record bit shifts. */
|
|
739
|
+
static void LJ_FASTCALL recff_bit_shift(jit_State *J, RecordFFData *rd)
|
|
740
|
+
{
|
|
741
|
+
#if LJ_HASFFI
|
|
742
|
+
if (recff_bit64_shift(J, rd))
|
|
743
|
+
return;
|
|
744
|
+
#endif
|
|
745
|
+
{
|
|
746
|
+
TRef tr = lj_opt_narrow_tobit(J, J->base[0]);
|
|
747
|
+
TRef tsh = lj_opt_narrow_tobit(J, J->base[1]);
|
|
748
|
+
IROp op = (IROp)rd->data;
|
|
749
|
+
if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
|
|
750
|
+
!tref_isk(tsh))
|
|
751
|
+
tsh = emitir(IRTI(IR_BAND), tsh, lj_ir_kint(J, 31));
|
|
752
|
+
#ifdef LJ_TARGET_UNIFYROT
|
|
753
|
+
if (op == (LJ_TARGET_UNIFYROT == 1 ? IR_BROR : IR_BROL)) {
|
|
754
|
+
op = LJ_TARGET_UNIFYROT == 1 ? IR_BROL : IR_BROR;
|
|
755
|
+
tsh = emitir(IRTI(IR_NEG), tsh, tsh);
|
|
756
|
+
}
|
|
757
|
+
#endif
|
|
758
|
+
J->base[0] = emitir(IRTI(op), tr, tsh);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
static void LJ_FASTCALL recff_bit_tohex(jit_State *J, RecordFFData *rd)
|
|
763
|
+
{
|
|
764
|
+
#if LJ_HASFFI
|
|
765
|
+
TRef hdr = recff_bufhdr(J);
|
|
766
|
+
TRef tr = recff_bit64_tohex(J, rd, hdr);
|
|
767
|
+
J->base[0] = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr);
|
|
768
|
+
#else
|
|
769
|
+
recff_nyiu(J, rd); /* Don't bother working around this NYI. */
|
|
770
|
+
#endif
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/* -- String library fast functions --------------------------------------- */
|
|
774
|
+
|
|
775
|
+
/* Specialize to relative starting position for string. */
|
|
776
|
+
static TRef recff_string_start(jit_State *J, GCstr *s, int32_t *st, TRef tr,
|
|
777
|
+
TRef trlen, TRef tr0)
|
|
778
|
+
{
|
|
779
|
+
int32_t start = *st;
|
|
780
|
+
if (start < 0) {
|
|
781
|
+
emitir(IRTGI(IR_LT), tr, tr0);
|
|
782
|
+
tr = emitir(IRTI(IR_ADD), trlen, tr);
|
|
783
|
+
start = start + (int32_t)s->len;
|
|
784
|
+
emitir(start < 0 ? IRTGI(IR_LT) : IRTGI(IR_GE), tr, tr0);
|
|
785
|
+
if (start < 0) {
|
|
786
|
+
tr = tr0;
|
|
787
|
+
start = 0;
|
|
788
|
+
}
|
|
789
|
+
} else if (start == 0) {
|
|
790
|
+
emitir(IRTGI(IR_EQ), tr, tr0);
|
|
791
|
+
tr = tr0;
|
|
792
|
+
} else {
|
|
793
|
+
tr = emitir(IRTI(IR_ADD), tr, lj_ir_kint(J, -1));
|
|
794
|
+
emitir(IRTGI(IR_GE), tr, tr0);
|
|
795
|
+
start--;
|
|
796
|
+
}
|
|
797
|
+
*st = start;
|
|
798
|
+
return tr;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/* Handle string.byte (rd->data = 0) and string.sub (rd->data = 1). */
|
|
802
|
+
static void LJ_FASTCALL recff_string_range(jit_State *J, RecordFFData *rd)
|
|
803
|
+
{
|
|
804
|
+
TRef trstr = lj_ir_tostr(J, J->base[0]);
|
|
805
|
+
TRef trlen = emitir(IRTI(IR_FLOAD), trstr, IRFL_STR_LEN);
|
|
806
|
+
TRef tr0 = lj_ir_kint(J, 0);
|
|
807
|
+
TRef trstart, trend;
|
|
808
|
+
GCstr *str = argv2str(J, &rd->argv[0]);
|
|
809
|
+
int32_t start, end;
|
|
810
|
+
if (rd->data) { /* string.sub(str, start [,end]) */
|
|
811
|
+
start = argv2int(J, &rd->argv[1]);
|
|
812
|
+
trstart = lj_opt_narrow_toint(J, J->base[1]);
|
|
813
|
+
trend = J->base[2];
|
|
814
|
+
if (tref_isnil(trend)) {
|
|
815
|
+
trend = lj_ir_kint(J, -1);
|
|
816
|
+
end = -1;
|
|
817
|
+
} else {
|
|
818
|
+
trend = lj_opt_narrow_toint(J, trend);
|
|
819
|
+
end = argv2int(J, &rd->argv[2]);
|
|
820
|
+
}
|
|
821
|
+
} else { /* string.byte(str, [,start [,end]]) */
|
|
822
|
+
if (tref_isnil(J->base[1])) {
|
|
823
|
+
start = 1;
|
|
824
|
+
trstart = lj_ir_kint(J, 1);
|
|
825
|
+
} else {
|
|
826
|
+
start = argv2int(J, &rd->argv[1]);
|
|
827
|
+
trstart = lj_opt_narrow_toint(J, J->base[1]);
|
|
828
|
+
}
|
|
829
|
+
if (J->base[1] && !tref_isnil(J->base[2])) {
|
|
830
|
+
trend = lj_opt_narrow_toint(J, J->base[2]);
|
|
831
|
+
end = argv2int(J, &rd->argv[2]);
|
|
832
|
+
} else {
|
|
833
|
+
trend = trstart;
|
|
834
|
+
end = start;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
if (end < 0) {
|
|
838
|
+
emitir(IRTGI(IR_LT), trend, tr0);
|
|
839
|
+
trend = emitir(IRTI(IR_ADD), emitir(IRTI(IR_ADD), trlen, trend),
|
|
840
|
+
lj_ir_kint(J, 1));
|
|
841
|
+
end = end+(int32_t)str->len+1;
|
|
842
|
+
} else if ((MSize)end <= str->len) {
|
|
843
|
+
emitir(IRTGI(IR_ULE), trend, trlen);
|
|
844
|
+
} else {
|
|
845
|
+
emitir(IRTGI(IR_UGT), trend, trlen);
|
|
846
|
+
end = (int32_t)str->len;
|
|
847
|
+
trend = trlen;
|
|
848
|
+
}
|
|
849
|
+
trstart = recff_string_start(J, str, &start, trstart, trlen, tr0);
|
|
850
|
+
if (rd->data) { /* Return string.sub result. */
|
|
851
|
+
if (end - start >= 0) {
|
|
852
|
+
/* Also handle empty range here, to avoid extra traces. */
|
|
853
|
+
TRef trptr, trslen = emitir(IRTI(IR_SUB), trend, trstart);
|
|
854
|
+
emitir(IRTGI(IR_GE), trslen, tr0);
|
|
855
|
+
trptr = emitir(IRT(IR_STRREF, IRT_P32), trstr, trstart);
|
|
856
|
+
J->base[0] = emitir(IRT(IR_SNEW, IRT_STR), trptr, trslen);
|
|
857
|
+
} else { /* Range underflow: return empty string. */
|
|
858
|
+
emitir(IRTGI(IR_LT), trend, trstart);
|
|
859
|
+
J->base[0] = lj_ir_kstr(J, &J2G(J)->strempty);
|
|
860
|
+
}
|
|
861
|
+
} else { /* Return string.byte result(s). */
|
|
862
|
+
ptrdiff_t i, len = end - start;
|
|
863
|
+
if (len > 0) {
|
|
864
|
+
TRef trslen = emitir(IRTI(IR_SUB), trend, trstart);
|
|
865
|
+
emitir(IRTGI(IR_EQ), trslen, lj_ir_kint(J, (int32_t)len));
|
|
866
|
+
if (J->baseslot + len > LJ_MAX_JSLOTS)
|
|
867
|
+
lj_trace_err_info(J, LJ_TRERR_STACKOV);
|
|
868
|
+
rd->nres = len;
|
|
869
|
+
for (i = 0; i < len; i++) {
|
|
870
|
+
TRef tmp = emitir(IRTI(IR_ADD), trstart, lj_ir_kint(J, (int32_t)i));
|
|
871
|
+
tmp = emitir(IRT(IR_STRREF, IRT_P32), trstr, tmp);
|
|
872
|
+
J->base[i] = emitir(IRT(IR_XLOAD, IRT_U8), tmp, IRXLOAD_READONLY);
|
|
873
|
+
}
|
|
874
|
+
} else { /* Empty range or range underflow: return no results. */
|
|
875
|
+
emitir(IRTGI(IR_LE), trend, trstart);
|
|
876
|
+
rd->nres = 0;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
static void LJ_FASTCALL recff_string_char(jit_State *J, RecordFFData *rd)
|
|
882
|
+
{
|
|
883
|
+
TRef k255 = lj_ir_kint(J, 255);
|
|
884
|
+
BCReg i;
|
|
885
|
+
for (i = 0; J->base[i] != 0; i++) { /* Convert char values to strings. */
|
|
886
|
+
TRef tr = lj_opt_narrow_toint(J, J->base[i]);
|
|
887
|
+
emitir(IRTGI(IR_ULE), tr, k255);
|
|
888
|
+
J->base[i] = emitir(IRT(IR_TOSTR, IRT_STR), tr, IRTOSTR_CHAR);
|
|
889
|
+
}
|
|
890
|
+
if (i > 1) { /* Concatenate the strings, if there's more than one. */
|
|
891
|
+
TRef hdr = recff_bufhdr(J), tr = hdr;
|
|
892
|
+
for (i = 0; J->base[i] != 0; i++)
|
|
893
|
+
tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr, J->base[i]);
|
|
894
|
+
J->base[0] = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr);
|
|
895
|
+
}
|
|
896
|
+
UNUSED(rd);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
static void LJ_FASTCALL recff_string_rep(jit_State *J, RecordFFData *rd)
|
|
900
|
+
{
|
|
901
|
+
TRef str = lj_ir_tostr(J, J->base[0]);
|
|
902
|
+
TRef rep = lj_opt_narrow_toint(J, J->base[1]);
|
|
903
|
+
TRef hdr, tr, str2 = 0;
|
|
904
|
+
if (!tref_isnil(J->base[2])) {
|
|
905
|
+
TRef sep = lj_ir_tostr(J, J->base[2]);
|
|
906
|
+
int32_t vrep = argv2int(J, &rd->argv[1]);
|
|
907
|
+
emitir(IRTGI(vrep > 1 ? IR_GT : IR_LE), rep, lj_ir_kint(J, 1));
|
|
908
|
+
if (vrep > 1) {
|
|
909
|
+
TRef hdr2 = recff_bufhdr(J);
|
|
910
|
+
TRef tr2 = emitir(IRT(IR_BUFPUT, IRT_P32), hdr2, sep);
|
|
911
|
+
tr2 = emitir(IRT(IR_BUFPUT, IRT_P32), tr2, str);
|
|
912
|
+
str2 = emitir(IRT(IR_BUFSTR, IRT_STR), tr2, hdr2);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
tr = hdr = recff_bufhdr(J);
|
|
916
|
+
if (str2) {
|
|
917
|
+
tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr, str);
|
|
918
|
+
str = str2;
|
|
919
|
+
rep = emitir(IRTI(IR_ADD), rep, lj_ir_kint(J, -1));
|
|
920
|
+
}
|
|
921
|
+
tr = lj_ir_call(J, IRCALL_lj_buf_putstr_rep, tr, str, rep);
|
|
922
|
+
J->base[0] = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr);
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
static void LJ_FASTCALL recff_string_op(jit_State *J, RecordFFData *rd)
|
|
926
|
+
{
|
|
927
|
+
TRef str = lj_ir_tostr(J, J->base[0]);
|
|
928
|
+
TRef hdr = recff_bufhdr(J);
|
|
929
|
+
TRef tr = lj_ir_call(J, rd->data, hdr, str);
|
|
930
|
+
J->base[0] = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr);
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
static void LJ_FASTCALL recff_string_find(jit_State *J, RecordFFData *rd)
|
|
934
|
+
{
|
|
935
|
+
TRef trstr = lj_ir_tostr(J, J->base[0]);
|
|
936
|
+
TRef trpat = lj_ir_tostr(J, J->base[1]);
|
|
937
|
+
TRef trlen = emitir(IRTI(IR_FLOAD), trstr, IRFL_STR_LEN);
|
|
938
|
+
TRef tr0 = lj_ir_kint(J, 0);
|
|
939
|
+
TRef trstart;
|
|
940
|
+
GCstr *str = argv2str(J, &rd->argv[0]);
|
|
941
|
+
GCstr *pat = argv2str(J, &rd->argv[1]);
|
|
942
|
+
int32_t start;
|
|
943
|
+
J->needsnap = 1;
|
|
944
|
+
if (tref_isnil(J->base[2])) {
|
|
945
|
+
trstart = lj_ir_kint(J, 1);
|
|
946
|
+
start = 1;
|
|
947
|
+
} else {
|
|
948
|
+
trstart = lj_opt_narrow_toint(J, J->base[2]);
|
|
949
|
+
start = argv2int(J, &rd->argv[2]);
|
|
950
|
+
}
|
|
951
|
+
trstart = recff_string_start(J, str, &start, trstart, trlen, tr0);
|
|
952
|
+
if ((MSize)start <= str->len) {
|
|
953
|
+
emitir(IRTGI(IR_ULE), trstart, trlen);
|
|
954
|
+
} else {
|
|
955
|
+
emitir(IRTGI(IR_UGT), trstart, trlen);
|
|
956
|
+
#if LJ_52
|
|
957
|
+
J->base[0] = TREF_NIL;
|
|
958
|
+
return;
|
|
959
|
+
#else
|
|
960
|
+
trstart = trlen;
|
|
961
|
+
start = str->len;
|
|
962
|
+
#endif
|
|
963
|
+
}
|
|
964
|
+
/* Fixed arg or no pattern matching chars? (Specialized to pattern string.) */
|
|
965
|
+
if ((J->base[2] && tref_istruecond(J->base[3])) ||
|
|
966
|
+
(emitir(IRTG(IR_EQ, IRT_STR), trpat, lj_ir_kstr(J, pat)),
|
|
967
|
+
!lj_str_haspattern(pat))) { /* Search for fixed string. */
|
|
968
|
+
TRef trsptr = emitir(IRT(IR_STRREF, IRT_P32), trstr, trstart);
|
|
969
|
+
TRef trpptr = emitir(IRT(IR_STRREF, IRT_P32), trpat, tr0);
|
|
970
|
+
TRef trslen = emitir(IRTI(IR_SUB), trlen, trstart);
|
|
971
|
+
TRef trplen = emitir(IRTI(IR_FLOAD), trpat, IRFL_STR_LEN);
|
|
972
|
+
TRef tr = lj_ir_call(J, IRCALL_lj_str_find, trsptr, trpptr, trslen, trplen);
|
|
973
|
+
TRef trp0 = lj_ir_kkptr(J, NULL);
|
|
974
|
+
if (lj_str_find(strdata(str)+(MSize)start, strdata(pat),
|
|
975
|
+
str->len-(MSize)start, pat->len)) {
|
|
976
|
+
TRef pos;
|
|
977
|
+
emitir(IRTG(IR_NE, IRT_P32), tr, trp0);
|
|
978
|
+
pos = emitir(IRTI(IR_SUB), tr, emitir(IRT(IR_STRREF, IRT_P32), trstr, tr0));
|
|
979
|
+
J->base[0] = emitir(IRTI(IR_ADD), pos, lj_ir_kint(J, 1));
|
|
980
|
+
J->base[1] = emitir(IRTI(IR_ADD), pos, trplen);
|
|
981
|
+
rd->nres = 2;
|
|
982
|
+
} else {
|
|
983
|
+
emitir(IRTG(IR_EQ, IRT_P32), tr, trp0);
|
|
984
|
+
J->base[0] = TREF_NIL;
|
|
985
|
+
}
|
|
986
|
+
} else { /* Search for pattern. */
|
|
987
|
+
recff_nyiu(J, rd);
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
static void LJ_FASTCALL recff_string_format(jit_State *J, RecordFFData *rd)
|
|
993
|
+
{
|
|
994
|
+
TRef trfmt = lj_ir_tostr(J, J->base[0]);
|
|
995
|
+
GCstr *fmt = argv2str(J, &rd->argv[0]);
|
|
996
|
+
int arg = 1;
|
|
997
|
+
TRef hdr, tr;
|
|
998
|
+
FormatState fs;
|
|
999
|
+
SFormat sf;
|
|
1000
|
+
/* Specialize to the format string. */
|
|
1001
|
+
emitir(IRTG(IR_EQ, IRT_STR), trfmt, lj_ir_kstr(J, fmt));
|
|
1002
|
+
tr = hdr = recff_bufhdr(J);
|
|
1003
|
+
lj_strfmt_init(&fs, strdata(fmt), fmt->len);
|
|
1004
|
+
while ((sf = lj_strfmt_parse(&fs)) != STRFMT_EOF) { /* Parse format. */
|
|
1005
|
+
TRef tra = sf == STRFMT_LIT ? 0 : J->base[arg++];
|
|
1006
|
+
TRef trsf = lj_ir_kint(J, (int32_t)sf);
|
|
1007
|
+
IRCallID id;
|
|
1008
|
+
switch (STRFMT_TYPE(sf)) {
|
|
1009
|
+
case STRFMT_LIT:
|
|
1010
|
+
tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr,
|
|
1011
|
+
lj_ir_kstr(J, lj_str_new(J->L, fs.str, fs.len)));
|
|
1012
|
+
break;
|
|
1013
|
+
case STRFMT_INT:
|
|
1014
|
+
id = IRCALL_lj_strfmt_putfnum_int;
|
|
1015
|
+
handle_int:
|
|
1016
|
+
if (!tref_isinteger(tra))
|
|
1017
|
+
goto handle_num;
|
|
1018
|
+
if (sf == STRFMT_INT) { /* Shortcut for plain %d. */
|
|
1019
|
+
tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr,
|
|
1020
|
+
emitir(IRT(IR_TOSTR, IRT_STR), tra, IRTOSTR_INT));
|
|
1021
|
+
} else {
|
|
1022
|
+
#if LJ_HASFFI
|
|
1023
|
+
tra = emitir(IRT(IR_CONV, IRT_U64), tra,
|
|
1024
|
+
(IRT_INT|(IRT_U64<<5)|IRCONV_SEXT));
|
|
1025
|
+
tr = lj_ir_call(J, IRCALL_lj_strfmt_putfxint, tr, trsf, tra);
|
|
1026
|
+
lj_needsplit(J);
|
|
1027
|
+
#else
|
|
1028
|
+
recff_nyiu(J, rd); /* Don't bother working around this NYI. */
|
|
1029
|
+
return;
|
|
1030
|
+
#endif
|
|
1031
|
+
}
|
|
1032
|
+
break;
|
|
1033
|
+
case STRFMT_UINT:
|
|
1034
|
+
id = IRCALL_lj_strfmt_putfnum_uint;
|
|
1035
|
+
goto handle_int;
|
|
1036
|
+
case STRFMT_NUM:
|
|
1037
|
+
id = IRCALL_lj_strfmt_putfnum;
|
|
1038
|
+
handle_num:
|
|
1039
|
+
tra = lj_ir_tonum(J, tra);
|
|
1040
|
+
tr = lj_ir_call(J, id, tr, trsf, tra);
|
|
1041
|
+
if (LJ_SOFTFP) lj_needsplit(J);
|
|
1042
|
+
break;
|
|
1043
|
+
case STRFMT_STR:
|
|
1044
|
+
if (!tref_isstr(tra)) {
|
|
1045
|
+
recff_nyiu(J, rd); /* NYI: __tostring and non-string types for %s. */
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1048
|
+
if (sf == STRFMT_STR) /* Shortcut for plain %s. */
|
|
1049
|
+
tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr, tra);
|
|
1050
|
+
else if ((sf & STRFMT_T_QUOTED))
|
|
1051
|
+
tr = lj_ir_call(J, IRCALL_lj_strfmt_putquoted, tr, tra);
|
|
1052
|
+
else
|
|
1053
|
+
tr = lj_ir_call(J, IRCALL_lj_strfmt_putfstr, tr, trsf, tra);
|
|
1054
|
+
break;
|
|
1055
|
+
case STRFMT_CHAR:
|
|
1056
|
+
tra = lj_opt_narrow_toint(J, tra);
|
|
1057
|
+
if (sf == STRFMT_CHAR) /* Shortcut for plain %c. */
|
|
1058
|
+
tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr,
|
|
1059
|
+
emitir(IRT(IR_TOSTR, IRT_STR), tra, IRTOSTR_CHAR));
|
|
1060
|
+
else
|
|
1061
|
+
tr = lj_ir_call(J, IRCALL_lj_strfmt_putfchar, tr, trsf, tra);
|
|
1062
|
+
break;
|
|
1063
|
+
case STRFMT_PTR: /* NYI */
|
|
1064
|
+
case STRFMT_ERR:
|
|
1065
|
+
default:
|
|
1066
|
+
recff_nyiu(J, rd);
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
J->base[0] = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr);
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
/* -- Table library fast functions ---------------------------------------- */
|
|
1074
|
+
|
|
1075
|
+
static void LJ_FASTCALL recff_table_insert(jit_State *J, RecordFFData *rd)
|
|
1076
|
+
{
|
|
1077
|
+
RecordIndex ix;
|
|
1078
|
+
ix.tab = J->base[0];
|
|
1079
|
+
ix.val = J->base[1];
|
|
1080
|
+
rd->nres = 0;
|
|
1081
|
+
if (tref_istab(ix.tab) && ix.val) {
|
|
1082
|
+
if (!J->base[2]) { /* Simple push: t[#t+1] = v */
|
|
1083
|
+
TRef trlen = lj_ir_call(J, IRCALL_lj_tab_len, ix.tab);
|
|
1084
|
+
GCtab *t = tabV(&rd->argv[0]);
|
|
1085
|
+
ix.key = emitir(IRTI(IR_ADD), trlen, lj_ir_kint(J, 1));
|
|
1086
|
+
settabV(J->L, &ix.tabv, t);
|
|
1087
|
+
setintV(&ix.keyv, lj_tab_len(t) + 1);
|
|
1088
|
+
ix.idxchain = 0;
|
|
1089
|
+
lj_record_idx(J, &ix); /* Set new value. */
|
|
1090
|
+
} else { /* Complex case: insert in the middle. */
|
|
1091
|
+
recff_nyiu(J, rd);
|
|
1092
|
+
return;
|
|
1093
|
+
}
|
|
1094
|
+
} /* else: Interpreter will throw. */
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
static void LJ_FASTCALL recff_table_concat(jit_State *J, RecordFFData *rd)
|
|
1098
|
+
{
|
|
1099
|
+
TRef tab = J->base[0];
|
|
1100
|
+
if (tref_istab(tab)) {
|
|
1101
|
+
TRef sep = !tref_isnil(J->base[1]) ?
|
|
1102
|
+
lj_ir_tostr(J, J->base[1]) : lj_ir_knull(J, IRT_STR);
|
|
1103
|
+
TRef tri = (J->base[1] && !tref_isnil(J->base[2])) ?
|
|
1104
|
+
lj_opt_narrow_toint(J, J->base[2]) : lj_ir_kint(J, 1);
|
|
1105
|
+
TRef tre = (J->base[1] && J->base[2] && !tref_isnil(J->base[3])) ?
|
|
1106
|
+
lj_opt_narrow_toint(J, J->base[3]) :
|
|
1107
|
+
lj_ir_call(J, IRCALL_lj_tab_len, tab);
|
|
1108
|
+
TRef hdr = recff_bufhdr(J);
|
|
1109
|
+
TRef tr = lj_ir_call(J, IRCALL_lj_buf_puttab, hdr, tab, sep, tri, tre);
|
|
1110
|
+
emitir(IRTG(IR_NE, IRT_PTR), tr, lj_ir_kptr(J, NULL));
|
|
1111
|
+
J->base[0] = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr);
|
|
1112
|
+
} /* else: Interpreter will throw. */
|
|
1113
|
+
UNUSED(rd);
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
static void LJ_FASTCALL recff_table_new(jit_State *J, RecordFFData *rd)
|
|
1117
|
+
{
|
|
1118
|
+
TRef tra = lj_opt_narrow_toint(J, J->base[0]);
|
|
1119
|
+
TRef trh = lj_opt_narrow_toint(J, J->base[1]);
|
|
1120
|
+
J->base[0] = lj_ir_call(J, IRCALL_lj_tab_new_ah, tra, trh);
|
|
1121
|
+
UNUSED(rd);
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
static void LJ_FASTCALL recff_table_clear(jit_State *J, RecordFFData *rd)
|
|
1125
|
+
{
|
|
1126
|
+
TRef tr = J->base[0];
|
|
1127
|
+
if (tref_istab(tr)) {
|
|
1128
|
+
rd->nres = 0;
|
|
1129
|
+
lj_ir_call(J, IRCALL_lj_tab_clear, tr);
|
|
1130
|
+
J->needsnap = 1;
|
|
1131
|
+
} /* else: Interpreter will throw. */
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
/* -- I/O library fast functions ------------------------------------------ */
|
|
1135
|
+
|
|
1136
|
+
/* Get FILE* for I/O function. Any I/O error aborts recording, so there's
|
|
1137
|
+
** no need to encode the alternate cases for any of the guards.
|
|
1138
|
+
*/
|
|
1139
|
+
static TRef recff_io_fp(jit_State *J, TRef *udp, int32_t id)
|
|
1140
|
+
{
|
|
1141
|
+
TRef tr, ud, fp;
|
|
1142
|
+
if (id) { /* io.func() */
|
|
1143
|
+
tr = lj_ir_kptr(J, &J2G(J)->gcroot[id]);
|
|
1144
|
+
ud = emitir(IRT(IR_XLOAD, IRT_UDATA), tr, 0);
|
|
1145
|
+
} else { /* fp:method() */
|
|
1146
|
+
ud = J->base[0];
|
|
1147
|
+
if (!tref_isudata(ud))
|
|
1148
|
+
lj_trace_err(J, LJ_TRERR_BADTYPE);
|
|
1149
|
+
tr = emitir(IRT(IR_FLOAD, IRT_U8), ud, IRFL_UDATA_UDTYPE);
|
|
1150
|
+
emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, UDTYPE_IO_FILE));
|
|
1151
|
+
}
|
|
1152
|
+
*udp = ud;
|
|
1153
|
+
fp = emitir(IRT(IR_FLOAD, IRT_PTR), ud, IRFL_UDATA_FILE);
|
|
1154
|
+
emitir(IRTG(IR_NE, IRT_PTR), fp, lj_ir_knull(J, IRT_PTR));
|
|
1155
|
+
return fp;
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
static void LJ_FASTCALL recff_io_write(jit_State *J, RecordFFData *rd)
|
|
1159
|
+
{
|
|
1160
|
+
TRef ud, fp = recff_io_fp(J, &ud, rd->data);
|
|
1161
|
+
TRef zero = lj_ir_kint(J, 0);
|
|
1162
|
+
TRef one = lj_ir_kint(J, 1);
|
|
1163
|
+
ptrdiff_t i = rd->data == 0 ? 1 : 0;
|
|
1164
|
+
for (; J->base[i]; i++) {
|
|
1165
|
+
TRef str = lj_ir_tostr(J, J->base[i]);
|
|
1166
|
+
TRef buf = emitir(IRT(IR_STRREF, IRT_P32), str, zero);
|
|
1167
|
+
TRef len = emitir(IRTI(IR_FLOAD), str, IRFL_STR_LEN);
|
|
1168
|
+
if (tref_isk(len) && IR(tref_ref(len))->i == 1) {
|
|
1169
|
+
IRIns *irs = IR(tref_ref(str));
|
|
1170
|
+
TRef tr = (irs->o == IR_TOSTR && irs->op2 == IRTOSTR_CHAR) ?
|
|
1171
|
+
irs->op1 :
|
|
1172
|
+
emitir(IRT(IR_XLOAD, IRT_U8), buf, IRXLOAD_READONLY);
|
|
1173
|
+
tr = lj_ir_call(J, IRCALL_fputc, tr, fp);
|
|
1174
|
+
if (results_wanted(J) != 0) /* Check result only if not ignored. */
|
|
1175
|
+
emitir(IRTGI(IR_NE), tr, lj_ir_kint(J, -1));
|
|
1176
|
+
} else {
|
|
1177
|
+
TRef tr = lj_ir_call(J, IRCALL_fwrite, buf, one, len, fp);
|
|
1178
|
+
if (results_wanted(J) != 0) /* Check result only if not ignored. */
|
|
1179
|
+
emitir(IRTGI(IR_EQ), tr, len);
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
J->base[0] = LJ_52 ? ud : TREF_TRUE;
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
static void LJ_FASTCALL recff_io_flush(jit_State *J, RecordFFData *rd)
|
|
1186
|
+
{
|
|
1187
|
+
TRef ud, fp = recff_io_fp(J, &ud, rd->data);
|
|
1188
|
+
TRef tr = lj_ir_call(J, IRCALL_fflush, fp);
|
|
1189
|
+
if (results_wanted(J) != 0) /* Check result only if not ignored. */
|
|
1190
|
+
emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, 0));
|
|
1191
|
+
J->base[0] = TREF_TRUE;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
/* -- Debug library fast functions ---------------------------------------- */
|
|
1195
|
+
|
|
1196
|
+
static void LJ_FASTCALL recff_debug_getmetatable(jit_State *J, RecordFFData *rd)
|
|
1197
|
+
{
|
|
1198
|
+
GCtab *mt;
|
|
1199
|
+
TRef mtref;
|
|
1200
|
+
TRef tr = J->base[0];
|
|
1201
|
+
if (tref_istab(tr)) {
|
|
1202
|
+
mt = tabref(tabV(&rd->argv[0])->metatable);
|
|
1203
|
+
mtref = emitir(IRT(IR_FLOAD, IRT_TAB), tr, IRFL_TAB_META);
|
|
1204
|
+
} else if (tref_isudata(tr)) {
|
|
1205
|
+
mt = tabref(udataV(&rd->argv[0])->metatable);
|
|
1206
|
+
mtref = emitir(IRT(IR_FLOAD, IRT_TAB), tr, IRFL_UDATA_META);
|
|
1207
|
+
} else {
|
|
1208
|
+
mt = tabref(basemt_obj(J2G(J), &rd->argv[0]));
|
|
1209
|
+
J->base[0] = mt ? lj_ir_ktab(J, mt) : TREF_NIL;
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mtref, lj_ir_knull(J, IRT_TAB));
|
|
1213
|
+
J->base[0] = mt ? mtref : TREF_NIL;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
/* -- Record calls to fast functions -------------------------------------- */
|
|
1217
|
+
|
|
1218
|
+
#include "lj_recdef.h"
|
|
1219
|
+
|
|
1220
|
+
static uint32_t recdef_lookup(GCfunc *fn)
|
|
1221
|
+
{
|
|
1222
|
+
if (fn->c.ffid < sizeof(recff_idmap)/sizeof(recff_idmap[0]))
|
|
1223
|
+
return recff_idmap[fn->c.ffid];
|
|
1224
|
+
else
|
|
1225
|
+
return 0;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
/* Record entry to a fast function or C function. */
|
|
1229
|
+
void lj_ffrecord_func(jit_State *J)
|
|
1230
|
+
{
|
|
1231
|
+
RecordFFData rd;
|
|
1232
|
+
uint32_t m = recdef_lookup(J->fn);
|
|
1233
|
+
rd.data = m & 0xff;
|
|
1234
|
+
rd.nres = 1; /* Default is one result. */
|
|
1235
|
+
rd.argv = J->L->base;
|
|
1236
|
+
J->base[J->maxslot] = 0; /* Mark end of arguments. */
|
|
1237
|
+
(recff_func[m >> 8])(J, &rd); /* Call recff_* handler. */
|
|
1238
|
+
if (rd.nres >= 0) {
|
|
1239
|
+
if (J->postproc == LJ_POST_NONE) J->postproc = LJ_POST_FFRETRY;
|
|
1240
|
+
lj_record_ret(J, 0, rd.nres);
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
#undef IR
|
|
1245
|
+
#undef emitir
|
|
1246
|
+
|
|
1247
|
+
#endif
|