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,4355 @@
|
|
1
|
+
|// Low-level VM code for MIPS CPUs.
|
2
|
+
|// Bytecode interpreter, fast functions and helper functions.
|
3
|
+
|// Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
4
|
+
|
|
5
|
+
|.arch mips
|
6
|
+
|.section code_op, code_sub
|
7
|
+
|
|
8
|
+
|.actionlist build_actionlist
|
9
|
+
|.globals GLOB_
|
10
|
+
|.globalnames globnames
|
11
|
+
|.externnames extnames
|
12
|
+
|
|
13
|
+
|// Note: The ragged indentation of the instructions is intentional.
|
14
|
+
|// The starting columns indicate data dependencies.
|
15
|
+
|
|
16
|
+
|//-----------------------------------------------------------------------
|
17
|
+
|
|
18
|
+
|// Fixed register assignments for the interpreter.
|
19
|
+
|// Don't use: r0 = 0, r26/r27 = reserved, r28 = gp, r29 = sp, r31 = ra
|
20
|
+
|
|
21
|
+
|// The following must be C callee-save (but BASE is often refetched).
|
22
|
+
|.define BASE, r16 // Base of current Lua stack frame.
|
23
|
+
|.define KBASE, r17 // Constants of current Lua function.
|
24
|
+
|.define PC, r18 // Next PC.
|
25
|
+
|.define DISPATCH, r19 // Opcode dispatch table.
|
26
|
+
|.define LREG, r20 // Register holding lua_State (also in SAVE_L).
|
27
|
+
|.define MULTRES, r21 // Size of multi-result: (nresults+1)*8.
|
28
|
+
|// NYI: r22 currently unused.
|
29
|
+
|
|
30
|
+
|.define JGL, r30 // On-trace: global_State + 32768.
|
31
|
+
|
|
32
|
+
|// Constants for type-comparisons, stores and conversions. C callee-save.
|
33
|
+
|.define TISNIL, r30
|
34
|
+
|.define TOBIT, f30 // 2^52 + 2^51.
|
35
|
+
|
|
36
|
+
|// The following temporaries are not saved across C calls, except for RA.
|
37
|
+
|.define RA, r23 // Callee-save.
|
38
|
+
|.define RB, r8
|
39
|
+
|.define RC, r9
|
40
|
+
|.define RD, r10
|
41
|
+
|.define INS, r11
|
42
|
+
|
|
43
|
+
|.define AT, r1 // Assembler temporary.
|
44
|
+
|.define TMP0, r12
|
45
|
+
|.define TMP1, r13
|
46
|
+
|.define TMP2, r14
|
47
|
+
|.define TMP3, r15
|
48
|
+
|
|
49
|
+
|// Calling conventions.
|
50
|
+
|.define CFUNCADDR, r25
|
51
|
+
|.define CARG1, r4
|
52
|
+
|.define CARG2, r5
|
53
|
+
|.define CARG3, r6
|
54
|
+
|.define CARG4, r7
|
55
|
+
|
|
56
|
+
|.define CRET1, r2
|
57
|
+
|.define CRET2, r3
|
58
|
+
|
|
59
|
+
|.define FARG1, f12
|
60
|
+
|.define FARG2, f14
|
61
|
+
|
|
62
|
+
|.define FRET1, f0
|
63
|
+
|.define FRET2, f2
|
64
|
+
|
|
65
|
+
|// Stack layout while in interpreter. Must match with lj_frame.h.
|
66
|
+
|.define CFRAME_SPACE, 112 // Delta for sp.
|
67
|
+
|
|
68
|
+
|.define SAVE_ERRF, 124(sp) // 32 bit C frame info.
|
69
|
+
|.define SAVE_NRES, 120(sp)
|
70
|
+
|.define SAVE_CFRAME, 116(sp)
|
71
|
+
|.define SAVE_L, 112(sp)
|
72
|
+
|//----- 8 byte aligned, ^^^^ 16 byte register save area, owned by interpreter.
|
73
|
+
|.define SAVE_GPR_, 72 // .. 72+10*4: 32 bit GPR saves.
|
74
|
+
|.define SAVE_FPR_, 24 // .. 24+6*8: 64 bit FPR saves.
|
75
|
+
|.define SAVE_PC, 20(sp)
|
76
|
+
|.define ARG5, 16(sp)
|
77
|
+
|.define CSAVE_4, 12(sp)
|
78
|
+
|.define CSAVE_3, 8(sp)
|
79
|
+
|.define CSAVE_2, 4(sp)
|
80
|
+
|.define CSAVE_1, 0(sp)
|
81
|
+
|//----- 8 byte aligned, ^^^^ 16 byte register save area, owned by callee.
|
82
|
+
|
|
83
|
+
|.define ARG5_OFS, 16
|
84
|
+
|.define SAVE_MULTRES, ARG5
|
85
|
+
|
|
86
|
+
|.macro saveregs
|
87
|
+
| addiu sp, sp, -CFRAME_SPACE
|
88
|
+
| sw ra, SAVE_GPR_+9*4(sp)
|
89
|
+
| sw r30, SAVE_GPR_+8*4(sp)
|
90
|
+
| sdc1 f30, SAVE_FPR_+5*8(sp)
|
91
|
+
| sw r23, SAVE_GPR_+7*4(sp)
|
92
|
+
| sw r22, SAVE_GPR_+6*4(sp)
|
93
|
+
| sdc1 f28, SAVE_FPR_+4*8(sp)
|
94
|
+
| sw r21, SAVE_GPR_+5*4(sp)
|
95
|
+
| sw r20, SAVE_GPR_+4*4(sp)
|
96
|
+
| sdc1 f26, SAVE_FPR_+3*8(sp)
|
97
|
+
| sw r19, SAVE_GPR_+3*4(sp)
|
98
|
+
| sw r18, SAVE_GPR_+2*4(sp)
|
99
|
+
| sdc1 f24, SAVE_FPR_+2*8(sp)
|
100
|
+
| sw r17, SAVE_GPR_+1*4(sp)
|
101
|
+
| sw r16, SAVE_GPR_+0*4(sp)
|
102
|
+
| sdc1 f22, SAVE_FPR_+1*8(sp)
|
103
|
+
| sdc1 f20, SAVE_FPR_+0*8(sp)
|
104
|
+
|.endmacro
|
105
|
+
|
|
106
|
+
|.macro restoreregs_ret
|
107
|
+
| lw ra, SAVE_GPR_+9*4(sp)
|
108
|
+
| lw r30, SAVE_GPR_+8*4(sp)
|
109
|
+
| ldc1 f30, SAVE_FPR_+5*8(sp)
|
110
|
+
| lw r23, SAVE_GPR_+7*4(sp)
|
111
|
+
| lw r22, SAVE_GPR_+6*4(sp)
|
112
|
+
| ldc1 f28, SAVE_FPR_+4*8(sp)
|
113
|
+
| lw r21, SAVE_GPR_+5*4(sp)
|
114
|
+
| lw r20, SAVE_GPR_+4*4(sp)
|
115
|
+
| ldc1 f26, SAVE_FPR_+3*8(sp)
|
116
|
+
| lw r19, SAVE_GPR_+3*4(sp)
|
117
|
+
| lw r18, SAVE_GPR_+2*4(sp)
|
118
|
+
| ldc1 f24, SAVE_FPR_+2*8(sp)
|
119
|
+
| lw r17, SAVE_GPR_+1*4(sp)
|
120
|
+
| lw r16, SAVE_GPR_+0*4(sp)
|
121
|
+
| ldc1 f22, SAVE_FPR_+1*8(sp)
|
122
|
+
| ldc1 f20, SAVE_FPR_+0*8(sp)
|
123
|
+
| jr ra
|
124
|
+
| addiu sp, sp, CFRAME_SPACE
|
125
|
+
|.endmacro
|
126
|
+
|
|
127
|
+
|// Type definitions. Some of these are only used for documentation.
|
128
|
+
|.type L, lua_State, LREG
|
129
|
+
|.type GL, global_State
|
130
|
+
|.type TVALUE, TValue
|
131
|
+
|.type GCOBJ, GCobj
|
132
|
+
|.type STR, GCstr
|
133
|
+
|.type TAB, GCtab
|
134
|
+
|.type LFUNC, GCfuncL
|
135
|
+
|.type CFUNC, GCfuncC
|
136
|
+
|.type PROTO, GCproto
|
137
|
+
|.type UPVAL, GCupval
|
138
|
+
|.type NODE, Node
|
139
|
+
|.type NARGS8, int
|
140
|
+
|.type TRACE, GCtrace
|
141
|
+
|.type SBUF, SBuf
|
142
|
+
|
|
143
|
+
|//-----------------------------------------------------------------------
|
144
|
+
|
|
145
|
+
|// Trap for not-yet-implemented parts.
|
146
|
+
|.macro NYI; .long 0xf0f0f0f0; .endmacro
|
147
|
+
|
|
148
|
+
|// Macros to mark delay slots.
|
149
|
+
|.macro ., a; a; .endmacro
|
150
|
+
|.macro ., a,b; a,b; .endmacro
|
151
|
+
|.macro ., a,b,c; a,b,c; .endmacro
|
152
|
+
|
|
153
|
+
|//-----------------------------------------------------------------------
|
154
|
+
|
|
155
|
+
|// Endian-specific defines.
|
156
|
+
|.define FRAME_PC, LJ_ENDIAN_SELECT(-4,-8)
|
157
|
+
|.define FRAME_FUNC, LJ_ENDIAN_SELECT(-8,-4)
|
158
|
+
|.define HI, LJ_ENDIAN_SELECT(4,0)
|
159
|
+
|.define LO, LJ_ENDIAN_SELECT(0,4)
|
160
|
+
|.define OFS_RD, LJ_ENDIAN_SELECT(2,0)
|
161
|
+
|.define OFS_RA, LJ_ENDIAN_SELECT(1,2)
|
162
|
+
|.define OFS_OP, LJ_ENDIAN_SELECT(0,3)
|
163
|
+
|
|
164
|
+
|// Instruction decode.
|
165
|
+
|.macro decode_OP1, dst, ins; andi dst, ins, 0xff; .endmacro
|
166
|
+
|.macro decode_OP4a, dst, ins; andi dst, ins, 0xff; .endmacro
|
167
|
+
|.macro decode_OP4b, dst; sll dst, dst, 2; .endmacro
|
168
|
+
|.macro decode_RC4a, dst, ins; srl dst, ins, 14; .endmacro
|
169
|
+
|.macro decode_RC4b, dst; andi dst, dst, 0x3fc; .endmacro
|
170
|
+
|.macro decode_RD4b, dst; sll dst, dst, 2; .endmacro
|
171
|
+
|.macro decode_RA8a, dst, ins; srl dst, ins, 5; .endmacro
|
172
|
+
|.macro decode_RA8b, dst; andi dst, dst, 0x7f8; .endmacro
|
173
|
+
|.macro decode_RB8a, dst, ins; srl dst, ins, 21; .endmacro
|
174
|
+
|.macro decode_RB8b, dst; andi dst, dst, 0x7f8; .endmacro
|
175
|
+
|.macro decode_RD8a, dst, ins; srl dst, ins, 16; .endmacro
|
176
|
+
|.macro decode_RD8b, dst; sll dst, dst, 3; .endmacro
|
177
|
+
|.macro decode_RDtoRC8, dst, src; andi dst, src, 0x7f8; .endmacro
|
178
|
+
|
|
179
|
+
|// Instruction fetch.
|
180
|
+
|.macro ins_NEXT1
|
181
|
+
| lw INS, 0(PC)
|
182
|
+
| addiu PC, PC, 4
|
183
|
+
|.endmacro
|
184
|
+
|// Instruction decode+dispatch.
|
185
|
+
|.macro ins_NEXT2
|
186
|
+
| decode_OP4a TMP1, INS
|
187
|
+
| decode_OP4b TMP1
|
188
|
+
| addu TMP0, DISPATCH, TMP1
|
189
|
+
| decode_RD8a RD, INS
|
190
|
+
| lw AT, 0(TMP0)
|
191
|
+
| decode_RA8a RA, INS
|
192
|
+
| decode_RD8b RD
|
193
|
+
| jr AT
|
194
|
+
| decode_RA8b RA
|
195
|
+
|.endmacro
|
196
|
+
|.macro ins_NEXT
|
197
|
+
| ins_NEXT1
|
198
|
+
| ins_NEXT2
|
199
|
+
|.endmacro
|
200
|
+
|
|
201
|
+
|// Instruction footer.
|
202
|
+
|.if 1
|
203
|
+
| // Replicated dispatch. Less unpredictable branches, but higher I-Cache use.
|
204
|
+
| .define ins_next, ins_NEXT
|
205
|
+
| .define ins_next_, ins_NEXT
|
206
|
+
| .define ins_next1, ins_NEXT1
|
207
|
+
| .define ins_next2, ins_NEXT2
|
208
|
+
|.else
|
209
|
+
| // Common dispatch. Lower I-Cache use, only one (very) unpredictable branch.
|
210
|
+
| // Affects only certain kinds of benchmarks (and only with -j off).
|
211
|
+
| .macro ins_next
|
212
|
+
| b ->ins_next
|
213
|
+
| .endmacro
|
214
|
+
| .macro ins_next1
|
215
|
+
| .endmacro
|
216
|
+
| .macro ins_next2
|
217
|
+
| b ->ins_next
|
218
|
+
| .endmacro
|
219
|
+
| .macro ins_next_
|
220
|
+
| ->ins_next:
|
221
|
+
| ins_NEXT
|
222
|
+
| .endmacro
|
223
|
+
|.endif
|
224
|
+
|
|
225
|
+
|// Call decode and dispatch.
|
226
|
+
|.macro ins_callt
|
227
|
+
| // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, FRAME_PC(BASE) = PC
|
228
|
+
| lw PC, LFUNC:RB->pc
|
229
|
+
| lw INS, 0(PC)
|
230
|
+
| addiu PC, PC, 4
|
231
|
+
| decode_OP4a TMP1, INS
|
232
|
+
| decode_RA8a RA, INS
|
233
|
+
| decode_OP4b TMP1
|
234
|
+
| decode_RA8b RA
|
235
|
+
| addu TMP0, DISPATCH, TMP1
|
236
|
+
| lw TMP0, 0(TMP0)
|
237
|
+
| jr TMP0
|
238
|
+
| addu RA, RA, BASE
|
239
|
+
|.endmacro
|
240
|
+
|
|
241
|
+
|.macro ins_call
|
242
|
+
| // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, PC = caller PC
|
243
|
+
| sw PC, FRAME_PC(BASE)
|
244
|
+
| ins_callt
|
245
|
+
|.endmacro
|
246
|
+
|
|
247
|
+
|//-----------------------------------------------------------------------
|
248
|
+
|
|
249
|
+
|.macro branch_RD
|
250
|
+
| srl TMP0, RD, 1
|
251
|
+
| lui AT, (-(BCBIAS_J*4 >> 16) & 65535)
|
252
|
+
| addu TMP0, TMP0, AT
|
253
|
+
| addu PC, PC, TMP0
|
254
|
+
|.endmacro
|
255
|
+
|
|
256
|
+
|// Assumes DISPATCH is relative to GL.
|
257
|
+
#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field))
|
258
|
+
#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field))
|
259
|
+
#define GG_DISP2GOT (GG_OFS(got) - GG_OFS(dispatch))
|
260
|
+
#define DISPATCH_GOT(name) (GG_DISP2GOT + 4*LJ_GOT_##name)
|
261
|
+
|
|
262
|
+
#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
|
263
|
+
|
|
264
|
+
|.macro load_got, func
|
265
|
+
| lw CFUNCADDR, DISPATCH_GOT(func)(DISPATCH)
|
266
|
+
|.endmacro
|
267
|
+
|// Much faster. Sadly, there's no easy way to force the required code layout.
|
268
|
+
|// .macro call_intern, func; bal extern func; .endmacro
|
269
|
+
|.macro call_intern, func; jalr CFUNCADDR; .endmacro
|
270
|
+
|.macro call_extern; jalr CFUNCADDR; .endmacro
|
271
|
+
|.macro jmp_extern; jr CFUNCADDR; .endmacro
|
272
|
+
|
|
273
|
+
|.macro hotcheck, delta, target
|
274
|
+
| srl TMP1, PC, 1
|
275
|
+
| andi TMP1, TMP1, 126
|
276
|
+
| addu TMP1, TMP1, DISPATCH
|
277
|
+
| lhu TMP2, GG_DISP2HOT(TMP1)
|
278
|
+
| addiu TMP2, TMP2, -delta
|
279
|
+
| bltz TMP2, target
|
280
|
+
|. sh TMP2, GG_DISP2HOT(TMP1)
|
281
|
+
|.endmacro
|
282
|
+
|
|
283
|
+
|.macro hotloop
|
284
|
+
| hotcheck HOTCOUNT_LOOP, ->vm_hotloop
|
285
|
+
|.endmacro
|
286
|
+
|
|
287
|
+
|.macro hotcall
|
288
|
+
| hotcheck HOTCOUNT_CALL, ->vm_hotcall
|
289
|
+
|.endmacro
|
290
|
+
|
|
291
|
+
|// Set current VM state. Uses TMP0.
|
292
|
+
|.macro li_vmstate, st; li TMP0, ~LJ_VMST_..st; .endmacro
|
293
|
+
|.macro st_vmstate; sw TMP0, DISPATCH_GL(vmstate)(DISPATCH); .endmacro
|
294
|
+
|
|
295
|
+
|// Move table write barrier back. Overwrites mark and tmp.
|
296
|
+
|.macro barrierback, tab, mark, tmp, target
|
297
|
+
| lw tmp, DISPATCH_GL(gc.grayagain)(DISPATCH)
|
298
|
+
| andi mark, mark, ~LJ_GC_BLACK & 255 // black2gray(tab)
|
299
|
+
| sw tab, DISPATCH_GL(gc.grayagain)(DISPATCH)
|
300
|
+
| sb mark, tab->marked
|
301
|
+
| b target
|
302
|
+
|. sw tmp, tab->gclist
|
303
|
+
|.endmacro
|
304
|
+
|
|
305
|
+
|//-----------------------------------------------------------------------
|
306
|
+
|
307
|
+
/* Generate subroutines used by opcodes and other parts of the VM. */
|
308
|
+
/* The .code_sub section should be last to help static branch prediction. */
|
309
|
+
static void build_subroutines(BuildCtx *ctx)
|
310
|
+
{
|
311
|
+
|.code_sub
|
312
|
+
|
|
313
|
+
|//-----------------------------------------------------------------------
|
314
|
+
|//-- Return handling ----------------------------------------------------
|
315
|
+
|//-----------------------------------------------------------------------
|
316
|
+
|
|
317
|
+
|->vm_returnp:
|
318
|
+
| // See vm_return. Also: TMP2 = previous base.
|
319
|
+
| andi AT, PC, FRAME_P
|
320
|
+
| beqz AT, ->cont_dispatch
|
321
|
+
|. li TMP1, LJ_TTRUE
|
322
|
+
|
|
323
|
+
| // Return from pcall or xpcall fast func.
|
324
|
+
| lw PC, FRAME_PC(TMP2) // Fetch PC of previous frame.
|
325
|
+
| move BASE, TMP2 // Restore caller base.
|
326
|
+
| // Prepending may overwrite the pcall frame, so do it at the end.
|
327
|
+
| sw TMP1, FRAME_PC(RA) // Prepend true to results.
|
328
|
+
| addiu RA, RA, -8
|
329
|
+
|
|
330
|
+
|->vm_returnc:
|
331
|
+
| addiu RD, RD, 8 // RD = (nresults+1)*8.
|
332
|
+
| andi TMP0, PC, FRAME_TYPE
|
333
|
+
| beqz RD, ->vm_unwind_c_eh
|
334
|
+
|. li CRET1, LUA_YIELD
|
335
|
+
| beqz TMP0, ->BC_RET_Z // Handle regular return to Lua.
|
336
|
+
|. move MULTRES, RD
|
337
|
+
|
|
338
|
+
|->vm_return:
|
339
|
+
| // BASE = base, RA = resultptr, RD/MULTRES = (nresults+1)*8, PC = return
|
340
|
+
| // TMP0 = PC & FRAME_TYPE
|
341
|
+
| li TMP2, -8
|
342
|
+
| xori AT, TMP0, FRAME_C
|
343
|
+
| and TMP2, PC, TMP2
|
344
|
+
| bnez AT, ->vm_returnp
|
345
|
+
| subu TMP2, BASE, TMP2 // TMP2 = previous base.
|
346
|
+
|
|
347
|
+
| addiu TMP1, RD, -8
|
348
|
+
| sw TMP2, L->base
|
349
|
+
| li_vmstate C
|
350
|
+
| lw TMP2, SAVE_NRES
|
351
|
+
| addiu BASE, BASE, -8
|
352
|
+
| st_vmstate
|
353
|
+
| beqz TMP1, >2
|
354
|
+
|. sll TMP2, TMP2, 3
|
355
|
+
|1:
|
356
|
+
| addiu TMP1, TMP1, -8
|
357
|
+
| ldc1 f0, 0(RA)
|
358
|
+
| addiu RA, RA, 8
|
359
|
+
| sdc1 f0, 0(BASE)
|
360
|
+
| bnez TMP1, <1
|
361
|
+
|. addiu BASE, BASE, 8
|
362
|
+
|
|
363
|
+
|2:
|
364
|
+
| bne TMP2, RD, >6
|
365
|
+
|3:
|
366
|
+
|. sw BASE, L->top // Store new top.
|
367
|
+
|
|
368
|
+
|->vm_leave_cp:
|
369
|
+
| lw TMP0, SAVE_CFRAME // Restore previous C frame.
|
370
|
+
| move CRET1, r0 // Ok return status for vm_pcall.
|
371
|
+
| sw TMP0, L->cframe
|
372
|
+
|
|
373
|
+
|->vm_leave_unw:
|
374
|
+
| restoreregs_ret
|
375
|
+
|
|
376
|
+
|6:
|
377
|
+
| lw TMP1, L->maxstack
|
378
|
+
| slt AT, TMP2, RD
|
379
|
+
| bnez AT, >7 // Less results wanted?
|
380
|
+
| // More results wanted. Check stack size and fill up results with nil.
|
381
|
+
|. slt AT, BASE, TMP1
|
382
|
+
| beqz AT, >8
|
383
|
+
|. nop
|
384
|
+
| sw TISNIL, HI(BASE)
|
385
|
+
| addiu RD, RD, 8
|
386
|
+
| b <2
|
387
|
+
|. addiu BASE, BASE, 8
|
388
|
+
|
|
389
|
+
|7: // Less results wanted.
|
390
|
+
| subu TMP0, RD, TMP2
|
391
|
+
| subu TMP0, BASE, TMP0 // Either keep top or shrink it.
|
392
|
+
| b <3
|
393
|
+
|. movn BASE, TMP0, TMP2 // LUA_MULTRET+1 case?
|
394
|
+
|
|
395
|
+
|8: // Corner case: need to grow stack for filling up results.
|
396
|
+
| // This can happen if:
|
397
|
+
| // - A C function grows the stack (a lot).
|
398
|
+
| // - The GC shrinks the stack in between.
|
399
|
+
| // - A return back from a lua_call() with (high) nresults adjustment.
|
400
|
+
| load_got lj_state_growstack
|
401
|
+
| move MULTRES, RD
|
402
|
+
| srl CARG2, TMP2, 3
|
403
|
+
| call_intern lj_state_growstack // (lua_State *L, int n)
|
404
|
+
|. move CARG1, L
|
405
|
+
| lw TMP2, SAVE_NRES
|
406
|
+
| lw BASE, L->top // Need the (realloced) L->top in BASE.
|
407
|
+
| move RD, MULTRES
|
408
|
+
| b <2
|
409
|
+
|. sll TMP2, TMP2, 3
|
410
|
+
|
|
411
|
+
|->vm_unwind_c: // Unwind C stack, return from vm_pcall.
|
412
|
+
| // (void *cframe, int errcode)
|
413
|
+
| move sp, CARG1
|
414
|
+
| move CRET1, CARG2
|
415
|
+
|->vm_unwind_c_eh: // Landing pad for external unwinder.
|
416
|
+
| lw L, SAVE_L
|
417
|
+
| li TMP0, ~LJ_VMST_C
|
418
|
+
| lw GL:TMP1, L->glref
|
419
|
+
| b ->vm_leave_unw
|
420
|
+
|. sw TMP0, GL:TMP1->vmstate
|
421
|
+
|
|
422
|
+
|->vm_unwind_ff: // Unwind C stack, return from ff pcall.
|
423
|
+
| // (void *cframe)
|
424
|
+
| li AT, -4
|
425
|
+
| and sp, CARG1, AT
|
426
|
+
|->vm_unwind_ff_eh: // Landing pad for external unwinder.
|
427
|
+
| lw L, SAVE_L
|
428
|
+
| lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
|
429
|
+
| li TISNIL, LJ_TNIL
|
430
|
+
| lw BASE, L->base
|
431
|
+
| lw DISPATCH, L->glref // Setup pointer to dispatch table.
|
432
|
+
| mtc1 TMP3, TOBIT
|
433
|
+
| li TMP1, LJ_TFALSE
|
434
|
+
| li_vmstate INTERP
|
435
|
+
| lw PC, FRAME_PC(BASE) // Fetch PC of previous frame.
|
436
|
+
| cvt.d.s TOBIT, TOBIT
|
437
|
+
| addiu RA, BASE, -8 // Results start at BASE-8.
|
438
|
+
| addiu DISPATCH, DISPATCH, GG_G2DISP
|
439
|
+
| sw TMP1, HI(RA) // Prepend false to error message.
|
440
|
+
| st_vmstate
|
441
|
+
| b ->vm_returnc
|
442
|
+
|. li RD, 16 // 2 results: false + error message.
|
443
|
+
|
|
444
|
+
|//-----------------------------------------------------------------------
|
445
|
+
|//-- Grow stack for calls -----------------------------------------------
|
446
|
+
|//-----------------------------------------------------------------------
|
447
|
+
|
|
448
|
+
|->vm_growstack_c: // Grow stack for C function.
|
449
|
+
| b >2
|
450
|
+
|. li CARG2, LUA_MINSTACK
|
451
|
+
|
|
452
|
+
|->vm_growstack_l: // Grow stack for Lua function.
|
453
|
+
| // BASE = new base, RA = BASE+framesize*8, RC = nargs*8, PC = first PC
|
454
|
+
| addu RC, BASE, RC
|
455
|
+
| subu RA, RA, BASE
|
456
|
+
| sw BASE, L->base
|
457
|
+
| addiu PC, PC, 4 // Must point after first instruction.
|
458
|
+
| sw RC, L->top
|
459
|
+
| srl CARG2, RA, 3
|
460
|
+
|2:
|
461
|
+
| // L->base = new base, L->top = top
|
462
|
+
| load_got lj_state_growstack
|
463
|
+
| sw PC, SAVE_PC
|
464
|
+
| call_intern lj_state_growstack // (lua_State *L, int n)
|
465
|
+
|. move CARG1, L
|
466
|
+
| lw BASE, L->base
|
467
|
+
| lw RC, L->top
|
468
|
+
| lw LFUNC:RB, FRAME_FUNC(BASE)
|
469
|
+
| subu RC, RC, BASE
|
470
|
+
| // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, FRAME_PC(BASE) = PC
|
471
|
+
| ins_callt // Just retry the call.
|
472
|
+
|
|
473
|
+
|//-----------------------------------------------------------------------
|
474
|
+
|//-- Entry points into the assembler VM ---------------------------------
|
475
|
+
|//-----------------------------------------------------------------------
|
476
|
+
|
|
477
|
+
|->vm_resume: // Setup C frame and resume thread.
|
478
|
+
| // (lua_State *L, TValue *base, int nres1 = 0, ptrdiff_t ef = 0)
|
479
|
+
| saveregs
|
480
|
+
| move L, CARG1
|
481
|
+
| lw DISPATCH, L->glref // Setup pointer to dispatch table.
|
482
|
+
| move BASE, CARG2
|
483
|
+
| lbu TMP1, L->status
|
484
|
+
| sw L, SAVE_L
|
485
|
+
| li PC, FRAME_CP
|
486
|
+
| addiu TMP0, sp, CFRAME_RESUME
|
487
|
+
| addiu DISPATCH, DISPATCH, GG_G2DISP
|
488
|
+
| sw r0, SAVE_NRES
|
489
|
+
| sw r0, SAVE_ERRF
|
490
|
+
| sw CARG1, SAVE_PC // Any value outside of bytecode is ok.
|
491
|
+
| sw r0, SAVE_CFRAME
|
492
|
+
| beqz TMP1, >3
|
493
|
+
|. sw TMP0, L->cframe
|
494
|
+
|
|
495
|
+
| // Resume after yield (like a return).
|
496
|
+
| sw L, DISPATCH_GL(cur_L)(DISPATCH)
|
497
|
+
| move RA, BASE
|
498
|
+
| lw BASE, L->base
|
499
|
+
| lw TMP1, L->top
|
500
|
+
| lw PC, FRAME_PC(BASE)
|
501
|
+
| lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
|
502
|
+
| subu RD, TMP1, BASE
|
503
|
+
| mtc1 TMP3, TOBIT
|
504
|
+
| sb r0, L->status
|
505
|
+
| cvt.d.s TOBIT, TOBIT
|
506
|
+
| li_vmstate INTERP
|
507
|
+
| addiu RD, RD, 8
|
508
|
+
| st_vmstate
|
509
|
+
| move MULTRES, RD
|
510
|
+
| andi TMP0, PC, FRAME_TYPE
|
511
|
+
| beqz TMP0, ->BC_RET_Z
|
512
|
+
|. li TISNIL, LJ_TNIL
|
513
|
+
| b ->vm_return
|
514
|
+
|. nop
|
515
|
+
|
|
516
|
+
|->vm_pcall: // Setup protected C frame and enter VM.
|
517
|
+
| // (lua_State *L, TValue *base, int nres1, ptrdiff_t ef)
|
518
|
+
| saveregs
|
519
|
+
| sw CARG4, SAVE_ERRF
|
520
|
+
| b >1
|
521
|
+
|. li PC, FRAME_CP
|
522
|
+
|
|
523
|
+
|->vm_call: // Setup C frame and enter VM.
|
524
|
+
| // (lua_State *L, TValue *base, int nres1)
|
525
|
+
| saveregs
|
526
|
+
| li PC, FRAME_C
|
527
|
+
|
|
528
|
+
|1: // Entry point for vm_pcall above (PC = ftype).
|
529
|
+
| lw TMP1, L:CARG1->cframe
|
530
|
+
| move L, CARG1
|
531
|
+
| sw CARG3, SAVE_NRES
|
532
|
+
| lw DISPATCH, L->glref // Setup pointer to dispatch table.
|
533
|
+
| sw CARG1, SAVE_L
|
534
|
+
| move BASE, CARG2
|
535
|
+
| addiu DISPATCH, DISPATCH, GG_G2DISP
|
536
|
+
| sw CARG1, SAVE_PC // Any value outside of bytecode is ok.
|
537
|
+
| sw TMP1, SAVE_CFRAME
|
538
|
+
| sw sp, L->cframe // Add our C frame to cframe chain.
|
539
|
+
|
|
540
|
+
|3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype).
|
541
|
+
| sw L, DISPATCH_GL(cur_L)(DISPATCH)
|
542
|
+
| lw TMP2, L->base // TMP2 = old base (used in vmeta_call).
|
543
|
+
| lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
|
544
|
+
| lw TMP1, L->top
|
545
|
+
| mtc1 TMP3, TOBIT
|
546
|
+
| addu PC, PC, BASE
|
547
|
+
| subu NARGS8:RC, TMP1, BASE
|
548
|
+
| subu PC, PC, TMP2 // PC = frame delta + frame type
|
549
|
+
| cvt.d.s TOBIT, TOBIT
|
550
|
+
| li_vmstate INTERP
|
551
|
+
| li TISNIL, LJ_TNIL
|
552
|
+
| st_vmstate
|
553
|
+
|
|
554
|
+
|->vm_call_dispatch:
|
555
|
+
| // TMP2 = old base, BASE = new base, RC = nargs*8, PC = caller PC
|
556
|
+
| lw TMP0, FRAME_PC(BASE)
|
557
|
+
| li AT, LJ_TFUNC
|
558
|
+
| bne TMP0, AT, ->vmeta_call
|
559
|
+
|. lw LFUNC:RB, FRAME_FUNC(BASE)
|
560
|
+
|
|
561
|
+
|->vm_call_dispatch_f:
|
562
|
+
| ins_call
|
563
|
+
| // BASE = new base, RB = func, RC = nargs*8, PC = caller PC
|
564
|
+
|
|
565
|
+
|->vm_cpcall: // Setup protected C frame, call C.
|
566
|
+
| // (lua_State *L, lua_CFunction func, void *ud, lua_CPFunction cp)
|
567
|
+
| saveregs
|
568
|
+
| move L, CARG1
|
569
|
+
| lw TMP0, L:CARG1->stack
|
570
|
+
| sw CARG1, SAVE_L
|
571
|
+
| lw TMP1, L->top
|
572
|
+
| lw DISPATCH, L->glref // Setup pointer to dispatch table.
|
573
|
+
| sw CARG1, SAVE_PC // Any value outside of bytecode is ok.
|
574
|
+
| subu TMP0, TMP0, TMP1 // Compute -savestack(L, L->top).
|
575
|
+
| lw TMP1, L->cframe
|
576
|
+
| addiu DISPATCH, DISPATCH, GG_G2DISP
|
577
|
+
| sw TMP0, SAVE_NRES // Neg. delta means cframe w/o frame.
|
578
|
+
| sw r0, SAVE_ERRF // No error function.
|
579
|
+
| sw TMP1, SAVE_CFRAME
|
580
|
+
| sw sp, L->cframe // Add our C frame to cframe chain.
|
581
|
+
| sw L, DISPATCH_GL(cur_L)(DISPATCH)
|
582
|
+
| jalr CARG4 // (lua_State *L, lua_CFunction func, void *ud)
|
583
|
+
|. move CFUNCADDR, CARG4
|
584
|
+
| move BASE, CRET1
|
585
|
+
| bnez CRET1, <3 // Else continue with the call.
|
586
|
+
|. li PC, FRAME_CP
|
587
|
+
| b ->vm_leave_cp // No base? Just remove C frame.
|
588
|
+
|. nop
|
589
|
+
|
|
590
|
+
|//-----------------------------------------------------------------------
|
591
|
+
|//-- Metamethod handling ------------------------------------------------
|
592
|
+
|//-----------------------------------------------------------------------
|
593
|
+
|
|
594
|
+
|// The lj_meta_* functions (except for lj_meta_cat) don't reallocate the
|
595
|
+
|// stack, so BASE doesn't need to be reloaded across these calls.
|
596
|
+
|
|
597
|
+
|//-- Continuation dispatch ----------------------------------------------
|
598
|
+
|
|
599
|
+
|->cont_dispatch:
|
600
|
+
| // BASE = meta base, RA = resultptr, RD = (nresults+1)*8
|
601
|
+
| lw TMP0, -16+LO(BASE) // Continuation.
|
602
|
+
| move RB, BASE
|
603
|
+
| move BASE, TMP2 // Restore caller BASE.
|
604
|
+
| lw LFUNC:TMP1, FRAME_FUNC(TMP2)
|
605
|
+
|.if FFI
|
606
|
+
| sltiu AT, TMP0, 2
|
607
|
+
|.endif
|
608
|
+
| lw PC, -16+HI(RB) // Restore PC from [cont|PC].
|
609
|
+
| addu TMP2, RA, RD
|
610
|
+
| lw TMP1, LFUNC:TMP1->pc
|
611
|
+
|.if FFI
|
612
|
+
| bnez AT, >1
|
613
|
+
|.endif
|
614
|
+
|. sw TISNIL, -8+HI(TMP2) // Ensure one valid arg.
|
615
|
+
| // BASE = base, RA = resultptr, RB = meta base
|
616
|
+
| jr TMP0 // Jump to continuation.
|
617
|
+
|. lw KBASE, PC2PROTO(k)(TMP1)
|
618
|
+
|
|
619
|
+
|.if FFI
|
620
|
+
|1:
|
621
|
+
| bnez TMP0, ->cont_ffi_callback // cont = 1: return from FFI callback.
|
622
|
+
| // cont = 0: tailcall from C function.
|
623
|
+
|. addiu TMP1, RB, -16
|
624
|
+
| b ->vm_call_tail
|
625
|
+
|. subu RC, TMP1, BASE
|
626
|
+
|.endif
|
627
|
+
|
|
628
|
+
|->cont_cat: // RA = resultptr, RB = meta base
|
629
|
+
| lw INS, -4(PC)
|
630
|
+
| addiu CARG2, RB, -16
|
631
|
+
| ldc1 f0, 0(RA)
|
632
|
+
| decode_RB8a MULTRES, INS
|
633
|
+
| decode_RA8a RA, INS
|
634
|
+
| decode_RB8b MULTRES
|
635
|
+
| decode_RA8b RA
|
636
|
+
| addu TMP1, BASE, MULTRES
|
637
|
+
| sw BASE, L->base
|
638
|
+
| subu CARG3, CARG2, TMP1
|
639
|
+
| bne TMP1, CARG2, ->BC_CAT_Z
|
640
|
+
|. sdc1 f0, 0(CARG2)
|
641
|
+
| addu RA, BASE, RA
|
642
|
+
| b ->cont_nop
|
643
|
+
|. sdc1 f0, 0(RA)
|
644
|
+
|
|
645
|
+
|//-- Table indexing metamethods -----------------------------------------
|
646
|
+
|
|
647
|
+
|->vmeta_tgets1:
|
648
|
+
| addiu CARG3, DISPATCH, DISPATCH_GL(tmptv)
|
649
|
+
| li TMP0, LJ_TSTR
|
650
|
+
| sw STR:RC, LO(CARG3)
|
651
|
+
| b >1
|
652
|
+
|. sw TMP0, HI(CARG3)
|
653
|
+
|
|
654
|
+
|->vmeta_tgets:
|
655
|
+
| addiu CARG2, DISPATCH, DISPATCH_GL(tmptv)
|
656
|
+
| li TMP0, LJ_TTAB
|
657
|
+
| sw TAB:RB, LO(CARG2)
|
658
|
+
| addiu CARG3, DISPATCH, DISPATCH_GL(tmptv2)
|
659
|
+
| sw TMP0, HI(CARG2)
|
660
|
+
| li TMP1, LJ_TSTR
|
661
|
+
| sw STR:RC, LO(CARG3)
|
662
|
+
| b >1
|
663
|
+
|. sw TMP1, HI(CARG3)
|
664
|
+
|
|
665
|
+
|->vmeta_tgetb: // TMP0 = index
|
666
|
+
| mtc1 TMP0, f0
|
667
|
+
| cvt.d.w f0, f0
|
668
|
+
| addiu CARG3, DISPATCH, DISPATCH_GL(tmptv)
|
669
|
+
| sdc1 f0, 0(CARG3)
|
670
|
+
|
|
671
|
+
|->vmeta_tgetv:
|
672
|
+
|1:
|
673
|
+
| load_got lj_meta_tget
|
674
|
+
| sw BASE, L->base
|
675
|
+
| sw PC, SAVE_PC
|
676
|
+
| call_intern lj_meta_tget // (lua_State *L, TValue *o, TValue *k)
|
677
|
+
|. move CARG1, L
|
678
|
+
| // Returns TValue * (finished) or NULL (metamethod).
|
679
|
+
| beqz CRET1, >3
|
680
|
+
|. addiu TMP1, BASE, -FRAME_CONT
|
681
|
+
| ldc1 f0, 0(CRET1)
|
682
|
+
| ins_next1
|
683
|
+
| sdc1 f0, 0(RA)
|
684
|
+
| ins_next2
|
685
|
+
|
|
686
|
+
|3: // Call __index metamethod.
|
687
|
+
| // BASE = base, L->top = new base, stack = cont/func/t/k
|
688
|
+
| lw BASE, L->top
|
689
|
+
| sw PC, -16+HI(BASE) // [cont|PC]
|
690
|
+
| subu PC, BASE, TMP1
|
691
|
+
| lw LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here.
|
692
|
+
| b ->vm_call_dispatch_f
|
693
|
+
|. li NARGS8:RC, 16 // 2 args for func(t, k).
|
694
|
+
|
|
695
|
+
|->vmeta_tgetr:
|
696
|
+
| load_got lj_tab_getinth
|
697
|
+
| call_intern lj_tab_getinth // (GCtab *t, int32_t key)
|
698
|
+
|. nop
|
699
|
+
| // Returns cTValue * or NULL.
|
700
|
+
| beqz CRET1, >1
|
701
|
+
|. nop
|
702
|
+
| b ->BC_TGETR_Z
|
703
|
+
|. ldc1 f0, 0(CRET1)
|
704
|
+
|
|
705
|
+
|//-----------------------------------------------------------------------
|
706
|
+
|
|
707
|
+
|->vmeta_tsets1:
|
708
|
+
| addiu CARG3, DISPATCH, DISPATCH_GL(tmptv)
|
709
|
+
| li TMP0, LJ_TSTR
|
710
|
+
| sw STR:RC, LO(CARG3)
|
711
|
+
| b >1
|
712
|
+
|. sw TMP0, HI(CARG3)
|
713
|
+
|
|
714
|
+
|->vmeta_tsets:
|
715
|
+
| addiu CARG2, DISPATCH, DISPATCH_GL(tmptv)
|
716
|
+
| li TMP0, LJ_TTAB
|
717
|
+
| sw TAB:RB, LO(CARG2)
|
718
|
+
| addiu CARG3, DISPATCH, DISPATCH_GL(tmptv2)
|
719
|
+
| sw TMP0, HI(CARG2)
|
720
|
+
| li TMP1, LJ_TSTR
|
721
|
+
| sw STR:RC, LO(CARG3)
|
722
|
+
| b >1
|
723
|
+
|. sw TMP1, HI(CARG3)
|
724
|
+
|
|
725
|
+
|->vmeta_tsetb: // TMP0 = index
|
726
|
+
| mtc1 TMP0, f0
|
727
|
+
| cvt.d.w f0, f0
|
728
|
+
| addiu CARG3, DISPATCH, DISPATCH_GL(tmptv)
|
729
|
+
| sdc1 f0, 0(CARG3)
|
730
|
+
|
|
731
|
+
|->vmeta_tsetv:
|
732
|
+
|1:
|
733
|
+
| load_got lj_meta_tset
|
734
|
+
| sw BASE, L->base
|
735
|
+
| sw PC, SAVE_PC
|
736
|
+
| call_intern lj_meta_tset // (lua_State *L, TValue *o, TValue *k)
|
737
|
+
|. move CARG1, L
|
738
|
+
| // Returns TValue * (finished) or NULL (metamethod).
|
739
|
+
| beqz CRET1, >3
|
740
|
+
|. ldc1 f0, 0(RA)
|
741
|
+
| // NOBARRIER: lj_meta_tset ensures the table is not black.
|
742
|
+
| ins_next1
|
743
|
+
| sdc1 f0, 0(CRET1)
|
744
|
+
| ins_next2
|
745
|
+
|
|
746
|
+
|3: // Call __newindex metamethod.
|
747
|
+
| // BASE = base, L->top = new base, stack = cont/func/t/k/(v)
|
748
|
+
| addiu TMP1, BASE, -FRAME_CONT
|
749
|
+
| lw BASE, L->top
|
750
|
+
| sw PC, -16+HI(BASE) // [cont|PC]
|
751
|
+
| subu PC, BASE, TMP1
|
752
|
+
| lw LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here.
|
753
|
+
| sdc1 f0, 16(BASE) // Copy value to third argument.
|
754
|
+
| b ->vm_call_dispatch_f
|
755
|
+
|. li NARGS8:RC, 24 // 3 args for func(t, k, v)
|
756
|
+
|
|
757
|
+
|->vmeta_tsetr:
|
758
|
+
| load_got lj_tab_setinth
|
759
|
+
| sw BASE, L->base
|
760
|
+
| sw PC, SAVE_PC
|
761
|
+
| call_intern lj_tab_setinth // (lua_State *L, GCtab *t, int32_t key)
|
762
|
+
|. move CARG1, L
|
763
|
+
| // Returns TValue *.
|
764
|
+
| b ->BC_TSETR_Z
|
765
|
+
|. nop
|
766
|
+
|
|
767
|
+
|//-- Comparison metamethods ---------------------------------------------
|
768
|
+
|
|
769
|
+
|->vmeta_comp:
|
770
|
+
| // CARG2, CARG3 are already set by BC_ISLT/BC_ISGE/BC_ISLE/BC_ISGT.
|
771
|
+
| load_got lj_meta_comp
|
772
|
+
| addiu PC, PC, -4
|
773
|
+
| sw BASE, L->base
|
774
|
+
| sw PC, SAVE_PC
|
775
|
+
| decode_OP1 CARG4, INS
|
776
|
+
| call_intern lj_meta_comp // (lua_State *L, TValue *o1, *o2, int op)
|
777
|
+
|. move CARG1, L
|
778
|
+
| // Returns 0/1 or TValue * (metamethod).
|
779
|
+
|3:
|
780
|
+
| sltiu AT, CRET1, 2
|
781
|
+
| beqz AT, ->vmeta_binop
|
782
|
+
| negu TMP2, CRET1
|
783
|
+
|4:
|
784
|
+
| lhu RD, OFS_RD(PC)
|
785
|
+
| addiu PC, PC, 4
|
786
|
+
| lui TMP1, (-(BCBIAS_J*4 >> 16) & 65535)
|
787
|
+
| sll RD, RD, 2
|
788
|
+
| addu RD, RD, TMP1
|
789
|
+
| and RD, RD, TMP2
|
790
|
+
| addu PC, PC, RD
|
791
|
+
|->cont_nop:
|
792
|
+
| ins_next
|
793
|
+
|
|
794
|
+
|->cont_ra: // RA = resultptr
|
795
|
+
| lbu TMP1, -4+OFS_RA(PC)
|
796
|
+
| ldc1 f0, 0(RA)
|
797
|
+
| sll TMP1, TMP1, 3
|
798
|
+
| addu TMP1, BASE, TMP1
|
799
|
+
| b ->cont_nop
|
800
|
+
|. sdc1 f0, 0(TMP1)
|
801
|
+
|
|
802
|
+
|->cont_condt: // RA = resultptr
|
803
|
+
| lw TMP0, HI(RA)
|
804
|
+
| sltiu AT, TMP0, LJ_TISTRUECOND
|
805
|
+
| b <4
|
806
|
+
|. negu TMP2, AT // Branch if result is true.
|
807
|
+
|
|
808
|
+
|->cont_condf: // RA = resultptr
|
809
|
+
| lw TMP0, HI(RA)
|
810
|
+
| sltiu AT, TMP0, LJ_TISTRUECOND
|
811
|
+
| b <4
|
812
|
+
|. addiu TMP2, AT, -1 // Branch if result is false.
|
813
|
+
|
|
814
|
+
|->vmeta_equal:
|
815
|
+
| // CARG2, CARG3, CARG4 are already set by BC_ISEQV/BC_ISNEV.
|
816
|
+
| load_got lj_meta_equal
|
817
|
+
| addiu PC, PC, -4
|
818
|
+
| sw BASE, L->base
|
819
|
+
| sw PC, SAVE_PC
|
820
|
+
| call_intern lj_meta_equal // (lua_State *L, GCobj *o1, *o2, int ne)
|
821
|
+
|. move CARG1, L
|
822
|
+
| // Returns 0/1 or TValue * (metamethod).
|
823
|
+
| b <3
|
824
|
+
|. nop
|
825
|
+
|
|
826
|
+
|->vmeta_equal_cd:
|
827
|
+
|.if FFI
|
828
|
+
| load_got lj_meta_equal_cd
|
829
|
+
| move CARG2, INS
|
830
|
+
| addiu PC, PC, -4
|
831
|
+
| sw BASE, L->base
|
832
|
+
| sw PC, SAVE_PC
|
833
|
+
| call_intern lj_meta_equal_cd // (lua_State *L, BCIns op)
|
834
|
+
|. move CARG1, L
|
835
|
+
| // Returns 0/1 or TValue * (metamethod).
|
836
|
+
| b <3
|
837
|
+
|. nop
|
838
|
+
|.endif
|
839
|
+
|
|
840
|
+
|->vmeta_istype:
|
841
|
+
| load_got lj_meta_istype
|
842
|
+
| addiu PC, PC, -4
|
843
|
+
| sw BASE, L->base
|
844
|
+
| srl CARG2, RA, 3
|
845
|
+
| srl CARG3, RD, 3
|
846
|
+
| sw PC, SAVE_PC
|
847
|
+
| call_intern lj_meta_istype // (lua_State *L, BCReg ra, BCReg tp)
|
848
|
+
|. move CARG1, L
|
849
|
+
| b ->cont_nop
|
850
|
+
|. nop
|
851
|
+
|
|
852
|
+
|//-- Arithmetic metamethods ---------------------------------------------
|
853
|
+
|
|
854
|
+
|->vmeta_unm:
|
855
|
+
| move CARG4, CARG3
|
856
|
+
|
|
857
|
+
|->vmeta_arith:
|
858
|
+
| load_got lj_meta_arith
|
859
|
+
| decode_OP1 TMP0, INS
|
860
|
+
| sw BASE, L->base
|
861
|
+
| sw PC, SAVE_PC
|
862
|
+
| move CARG2, RA
|
863
|
+
| sw TMP0, ARG5
|
864
|
+
| call_intern lj_meta_arith // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
|
865
|
+
|. move CARG1, L
|
866
|
+
| // Returns NULL (finished) or TValue * (metamethod).
|
867
|
+
| beqz CRET1, ->cont_nop
|
868
|
+
|. nop
|
869
|
+
|
|
870
|
+
| // Call metamethod for binary op.
|
871
|
+
|->vmeta_binop:
|
872
|
+
| // BASE = old base, CRET1 = new base, stack = cont/func/o1/o2
|
873
|
+
| subu TMP1, CRET1, BASE
|
874
|
+
| sw PC, -16+HI(CRET1) // [cont|PC]
|
875
|
+
| move TMP2, BASE
|
876
|
+
| addiu PC, TMP1, FRAME_CONT
|
877
|
+
| move BASE, CRET1
|
878
|
+
| b ->vm_call_dispatch
|
879
|
+
|. li NARGS8:RC, 16 // 2 args for func(o1, o2).
|
880
|
+
|
|
881
|
+
|->vmeta_len:
|
882
|
+
| // CARG2 already set by BC_LEN.
|
883
|
+
#if LJ_52
|
884
|
+
| move MULTRES, CARG1
|
885
|
+
#endif
|
886
|
+
| load_got lj_meta_len
|
887
|
+
| sw BASE, L->base
|
888
|
+
| sw PC, SAVE_PC
|
889
|
+
| call_intern lj_meta_len // (lua_State *L, TValue *o)
|
890
|
+
|. move CARG1, L
|
891
|
+
| // Returns NULL (retry) or TValue * (metamethod base).
|
892
|
+
#if LJ_52
|
893
|
+
| bnez CRET1, ->vmeta_binop // Binop call for compatibility.
|
894
|
+
|. nop
|
895
|
+
| b ->BC_LEN_Z
|
896
|
+
|. move CARG1, MULTRES
|
897
|
+
#else
|
898
|
+
| b ->vmeta_binop // Binop call for compatibility.
|
899
|
+
|. nop
|
900
|
+
#endif
|
901
|
+
|
|
902
|
+
|//-- Call metamethod ----------------------------------------------------
|
903
|
+
|
|
904
|
+
|->vmeta_call: // Resolve and call __call metamethod.
|
905
|
+
| // TMP2 = old base, BASE = new base, RC = nargs*8
|
906
|
+
| load_got lj_meta_call
|
907
|
+
| sw TMP2, L->base // This is the callers base!
|
908
|
+
| addiu CARG2, BASE, -8
|
909
|
+
| sw PC, SAVE_PC
|
910
|
+
| addu CARG3, BASE, RC
|
911
|
+
| move MULTRES, NARGS8:RC
|
912
|
+
| call_intern lj_meta_call // (lua_State *L, TValue *func, TValue *top)
|
913
|
+
|. move CARG1, L
|
914
|
+
| lw LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here.
|
915
|
+
| addiu NARGS8:RC, MULTRES, 8 // Got one more argument now.
|
916
|
+
| ins_call
|
917
|
+
|
|
918
|
+
|->vmeta_callt: // Resolve __call for BC_CALLT.
|
919
|
+
| // BASE = old base, RA = new base, RC = nargs*8
|
920
|
+
| load_got lj_meta_call
|
921
|
+
| sw BASE, L->base
|
922
|
+
| addiu CARG2, RA, -8
|
923
|
+
| sw PC, SAVE_PC
|
924
|
+
| addu CARG3, RA, RC
|
925
|
+
| move MULTRES, NARGS8:RC
|
926
|
+
| call_intern lj_meta_call // (lua_State *L, TValue *func, TValue *top)
|
927
|
+
|. move CARG1, L
|
928
|
+
| lw TMP1, FRAME_PC(BASE)
|
929
|
+
| lw LFUNC:RB, FRAME_FUNC(RA) // Guaranteed to be a function here.
|
930
|
+
| b ->BC_CALLT_Z
|
931
|
+
|. addiu NARGS8:RC, MULTRES, 8 // Got one more argument now.
|
932
|
+
|
|
933
|
+
|//-- Argument coercion for 'for' statement ------------------------------
|
934
|
+
|
|
935
|
+
|->vmeta_for:
|
936
|
+
| load_got lj_meta_for
|
937
|
+
| sw BASE, L->base
|
938
|
+
| move CARG2, RA
|
939
|
+
| sw PC, SAVE_PC
|
940
|
+
| move MULTRES, INS
|
941
|
+
| call_intern lj_meta_for // (lua_State *L, TValue *base)
|
942
|
+
|. move CARG1, L
|
943
|
+
|.if JIT
|
944
|
+
| decode_OP1 TMP0, MULTRES
|
945
|
+
| li AT, BC_JFORI
|
946
|
+
|.endif
|
947
|
+
| decode_RA8a RA, MULTRES
|
948
|
+
| decode_RD8a RD, MULTRES
|
949
|
+
| decode_RA8b RA
|
950
|
+
|.if JIT
|
951
|
+
| beq TMP0, AT, =>BC_JFORI
|
952
|
+
|. decode_RD8b RD
|
953
|
+
| b =>BC_FORI
|
954
|
+
|. nop
|
955
|
+
|.else
|
956
|
+
| b =>BC_FORI
|
957
|
+
|. decode_RD8b RD
|
958
|
+
|.endif
|
959
|
+
|
|
960
|
+
|//-----------------------------------------------------------------------
|
961
|
+
|//-- Fast functions -----------------------------------------------------
|
962
|
+
|//-----------------------------------------------------------------------
|
963
|
+
|
|
964
|
+
|.macro .ffunc, name
|
965
|
+
|->ff_ .. name:
|
966
|
+
|.endmacro
|
967
|
+
|
|
968
|
+
|.macro .ffunc_1, name
|
969
|
+
|->ff_ .. name:
|
970
|
+
| beqz NARGS8:RC, ->fff_fallback
|
971
|
+
|. lw CARG3, HI(BASE)
|
972
|
+
| lw CARG1, LO(BASE)
|
973
|
+
|.endmacro
|
974
|
+
|
|
975
|
+
|.macro .ffunc_2, name
|
976
|
+
|->ff_ .. name:
|
977
|
+
| sltiu AT, NARGS8:RC, 16
|
978
|
+
| lw CARG3, HI(BASE)
|
979
|
+
| bnez AT, ->fff_fallback
|
980
|
+
|. lw CARG4, 8+HI(BASE)
|
981
|
+
| lw CARG1, LO(BASE)
|
982
|
+
| lw CARG2, 8+LO(BASE)
|
983
|
+
|.endmacro
|
984
|
+
|
|
985
|
+
|.macro .ffunc_n, name // Caveat: has delay slot!
|
986
|
+
|->ff_ .. name:
|
987
|
+
| lw CARG3, HI(BASE)
|
988
|
+
| beqz NARGS8:RC, ->fff_fallback
|
989
|
+
|. ldc1 FARG1, 0(BASE)
|
990
|
+
| sltiu AT, CARG3, LJ_TISNUM
|
991
|
+
| beqz AT, ->fff_fallback
|
992
|
+
|.endmacro
|
993
|
+
|
|
994
|
+
|.macro .ffunc_nn, name // Caveat: has delay slot!
|
995
|
+
|->ff_ .. name:
|
996
|
+
| sltiu AT, NARGS8:RC, 16
|
997
|
+
| lw CARG3, HI(BASE)
|
998
|
+
| bnez AT, ->fff_fallback
|
999
|
+
|. lw CARG4, 8+HI(BASE)
|
1000
|
+
| ldc1 FARG1, 0(BASE)
|
1001
|
+
| ldc1 FARG2, 8(BASE)
|
1002
|
+
| sltiu TMP0, CARG3, LJ_TISNUM
|
1003
|
+
| sltiu TMP1, CARG4, LJ_TISNUM
|
1004
|
+
| and TMP0, TMP0, TMP1
|
1005
|
+
| beqz TMP0, ->fff_fallback
|
1006
|
+
|.endmacro
|
1007
|
+
|
|
1008
|
+
|// Inlined GC threshold check. Caveat: uses TMP0 and TMP1 and has delay slot!
|
1009
|
+
|.macro ffgccheck
|
1010
|
+
| lw TMP0, DISPATCH_GL(gc.total)(DISPATCH)
|
1011
|
+
| lw TMP1, DISPATCH_GL(gc.threshold)(DISPATCH)
|
1012
|
+
| subu AT, TMP0, TMP1
|
1013
|
+
| bgezal AT, ->fff_gcstep
|
1014
|
+
|.endmacro
|
1015
|
+
|
|
1016
|
+
|//-- Base library: checks -----------------------------------------------
|
1017
|
+
|
|
1018
|
+
|.ffunc_1 assert
|
1019
|
+
| sltiu AT, CARG3, LJ_TISTRUECOND
|
1020
|
+
| beqz AT, ->fff_fallback
|
1021
|
+
|. addiu RA, BASE, -8
|
1022
|
+
| lw PC, FRAME_PC(BASE)
|
1023
|
+
| addiu RD, NARGS8:RC, 8 // Compute (nresults+1)*8.
|
1024
|
+
| addu TMP2, RA, NARGS8:RC
|
1025
|
+
| sw CARG3, HI(RA)
|
1026
|
+
| addiu TMP1, BASE, 8
|
1027
|
+
| beq BASE, TMP2, ->fff_res // Done if exactly 1 argument.
|
1028
|
+
|. sw CARG1, LO(RA)
|
1029
|
+
|1:
|
1030
|
+
| ldc1 f0, 0(TMP1)
|
1031
|
+
| sdc1 f0, -8(TMP1)
|
1032
|
+
| bne TMP1, TMP2, <1
|
1033
|
+
|. addiu TMP1, TMP1, 8
|
1034
|
+
| b ->fff_res
|
1035
|
+
|. nop
|
1036
|
+
|
|
1037
|
+
|.ffunc type
|
1038
|
+
| lw CARG3, HI(BASE)
|
1039
|
+
| li TMP1, LJ_TISNUM
|
1040
|
+
| beqz NARGS8:RC, ->fff_fallback
|
1041
|
+
|. sltiu TMP0, CARG3, LJ_TISNUM
|
1042
|
+
| movz TMP1, CARG3, TMP0
|
1043
|
+
| not TMP1, TMP1
|
1044
|
+
| sll TMP1, TMP1, 3
|
1045
|
+
| addu TMP1, CFUNC:RB, TMP1
|
1046
|
+
| b ->fff_resn
|
1047
|
+
|. ldc1 FRET1, CFUNC:TMP1->upvalue
|
1048
|
+
|
|
1049
|
+
|//-- Base library: getters and setters ---------------------------------
|
1050
|
+
|
|
1051
|
+
|.ffunc_1 getmetatable
|
1052
|
+
| li AT, LJ_TTAB
|
1053
|
+
| bne CARG3, AT, >6
|
1054
|
+
|. li AT, LJ_TUDATA
|
1055
|
+
|1: // Field metatable must be at same offset for GCtab and GCudata!
|
1056
|
+
| lw TAB:CARG1, TAB:CARG1->metatable
|
1057
|
+
|2:
|
1058
|
+
| lw STR:RC, DISPATCH_GL(gcroot[GCROOT_MMNAME+MM_metatable])(DISPATCH)
|
1059
|
+
| beqz TAB:CARG1, ->fff_restv
|
1060
|
+
|. li CARG3, LJ_TNIL
|
1061
|
+
| lw TMP0, TAB:CARG1->hmask
|
1062
|
+
| li CARG3, LJ_TTAB // Use metatable as default result.
|
1063
|
+
| lw TMP1, STR:RC->hash
|
1064
|
+
| lw NODE:TMP2, TAB:CARG1->node
|
1065
|
+
| and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask
|
1066
|
+
| sll TMP0, TMP1, 5
|
1067
|
+
| sll TMP1, TMP1, 3
|
1068
|
+
| subu TMP1, TMP0, TMP1
|
1069
|
+
| addu NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8)
|
1070
|
+
| li AT, LJ_TSTR
|
1071
|
+
|3: // Rearranged logic, because we expect _not_ to find the key.
|
1072
|
+
| lw CARG4, offsetof(Node, key)+HI(NODE:TMP2)
|
1073
|
+
| lw TMP0, offsetof(Node, key)+LO(NODE:TMP2)
|
1074
|
+
| lw NODE:TMP3, NODE:TMP2->next
|
1075
|
+
| bne CARG4, AT, >4
|
1076
|
+
|. lw CARG2, offsetof(Node, val)+HI(NODE:TMP2)
|
1077
|
+
| beq TMP0, STR:RC, >5
|
1078
|
+
|. lw TMP1, offsetof(Node, val)+LO(NODE:TMP2)
|
1079
|
+
|4:
|
1080
|
+
| beqz NODE:TMP3, ->fff_restv // Not found, keep default result.
|
1081
|
+
|. move NODE:TMP2, NODE:TMP3
|
1082
|
+
| b <3
|
1083
|
+
|. nop
|
1084
|
+
|5:
|
1085
|
+
| beq CARG2, TISNIL, ->fff_restv // Ditto for nil value.
|
1086
|
+
|. nop
|
1087
|
+
| move CARG3, CARG2 // Return value of mt.__metatable.
|
1088
|
+
| b ->fff_restv
|
1089
|
+
|. move CARG1, TMP1
|
1090
|
+
|
|
1091
|
+
|6:
|
1092
|
+
| beq CARG3, AT, <1
|
1093
|
+
|. sltiu TMP0, CARG3, LJ_TISNUM
|
1094
|
+
| li TMP1, LJ_TISNUM
|
1095
|
+
| movz TMP1, CARG3, TMP0
|
1096
|
+
| not TMP1, TMP1
|
1097
|
+
| sll TMP1, TMP1, 2
|
1098
|
+
| addu TMP1, DISPATCH, TMP1
|
1099
|
+
| b <2
|
1100
|
+
|. lw TAB:CARG1, DISPATCH_GL(gcroot[GCROOT_BASEMT])(TMP1)
|
1101
|
+
|
|
1102
|
+
|.ffunc_2 setmetatable
|
1103
|
+
| // Fast path: no mt for table yet and not clearing the mt.
|
1104
|
+
| li AT, LJ_TTAB
|
1105
|
+
| bne CARG3, AT, ->fff_fallback
|
1106
|
+
|. addiu CARG4, CARG4, -LJ_TTAB
|
1107
|
+
| lw TAB:TMP1, TAB:CARG1->metatable
|
1108
|
+
| lbu TMP3, TAB:CARG1->marked
|
1109
|
+
| or AT, CARG4, TAB:TMP1
|
1110
|
+
| bnez AT, ->fff_fallback
|
1111
|
+
|. andi AT, TMP3, LJ_GC_BLACK // isblack(table)
|
1112
|
+
| beqz AT, ->fff_restv
|
1113
|
+
|. sw TAB:CARG2, TAB:CARG1->metatable
|
1114
|
+
| barrierback TAB:CARG1, TMP3, TMP0, ->fff_restv
|
1115
|
+
|
|
1116
|
+
|.ffunc rawget
|
1117
|
+
| lw CARG4, HI(BASE)
|
1118
|
+
| sltiu AT, NARGS8:RC, 16
|
1119
|
+
| lw TAB:CARG2, LO(BASE)
|
1120
|
+
| load_got lj_tab_get
|
1121
|
+
| addiu CARG4, CARG4, -LJ_TTAB
|
1122
|
+
| or AT, AT, CARG4
|
1123
|
+
| bnez AT, ->fff_fallback
|
1124
|
+
| addiu CARG3, BASE, 8
|
1125
|
+
| call_intern lj_tab_get // (lua_State *L, GCtab *t, cTValue *key)
|
1126
|
+
|. move CARG1, L
|
1127
|
+
| // Returns cTValue *.
|
1128
|
+
| b ->fff_resn
|
1129
|
+
|. ldc1 FRET1, 0(CRET1)
|
1130
|
+
|
|
1131
|
+
|//-- Base library: conversions ------------------------------------------
|
1132
|
+
|
|
1133
|
+
|.ffunc tonumber
|
1134
|
+
| // Only handles the number case inline (without a base argument).
|
1135
|
+
| lw CARG1, HI(BASE)
|
1136
|
+
| xori AT, NARGS8:RC, 8
|
1137
|
+
| sltiu CARG1, CARG1, LJ_TISNUM
|
1138
|
+
| movn CARG1, r0, AT
|
1139
|
+
| beqz CARG1, ->fff_fallback // Exactly one number argument.
|
1140
|
+
|. ldc1 FRET1, 0(BASE)
|
1141
|
+
| b ->fff_resn
|
1142
|
+
|. nop
|
1143
|
+
|
|
1144
|
+
|.ffunc_1 tostring
|
1145
|
+
| // Only handles the string or number case inline.
|
1146
|
+
| li AT, LJ_TSTR
|
1147
|
+
| // A __tostring method in the string base metatable is ignored.
|
1148
|
+
| beq CARG3, AT, ->fff_restv // String key?
|
1149
|
+
| // Handle numbers inline, unless a number base metatable is present.
|
1150
|
+
|. lw TMP1, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])(DISPATCH)
|
1151
|
+
| sltiu TMP0, CARG3, LJ_TISNUM
|
1152
|
+
| sltiu TMP1, TMP1, 1
|
1153
|
+
| and TMP0, TMP0, TMP1
|
1154
|
+
| beqz TMP0, ->fff_fallback
|
1155
|
+
|. sw BASE, L->base // Add frame since C call can throw.
|
1156
|
+
| ffgccheck
|
1157
|
+
|. sw PC, SAVE_PC // Redundant (but a defined value).
|
1158
|
+
| load_got lj_strfmt_num
|
1159
|
+
| move CARG1, L
|
1160
|
+
| call_intern lj_strfmt_num // (lua_State *L, lua_Number *np)
|
1161
|
+
|. move CARG2, BASE
|
1162
|
+
| // Returns GCstr *.
|
1163
|
+
| li CARG3, LJ_TSTR
|
1164
|
+
| b ->fff_restv
|
1165
|
+
|. move CARG1, CRET1
|
1166
|
+
|
|
1167
|
+
|//-- Base library: iterators -------------------------------------------
|
1168
|
+
|
|
1169
|
+
|.ffunc next
|
1170
|
+
| lw CARG1, HI(BASE)
|
1171
|
+
| lw TAB:CARG2, LO(BASE)
|
1172
|
+
| beqz NARGS8:RC, ->fff_fallback
|
1173
|
+
|. addu TMP2, BASE, NARGS8:RC
|
1174
|
+
| li AT, LJ_TTAB
|
1175
|
+
| sw TISNIL, HI(TMP2) // Set missing 2nd arg to nil.
|
1176
|
+
| bne CARG1, AT, ->fff_fallback
|
1177
|
+
|. lw PC, FRAME_PC(BASE)
|
1178
|
+
| load_got lj_tab_next
|
1179
|
+
| sw BASE, L->base // Add frame since C call can throw.
|
1180
|
+
| sw BASE, L->top // Dummy frame length is ok.
|
1181
|
+
| addiu CARG3, BASE, 8
|
1182
|
+
| sw PC, SAVE_PC
|
1183
|
+
| call_intern lj_tab_next // (lua_State *L, GCtab *t, TValue *key)
|
1184
|
+
|. move CARG1, L
|
1185
|
+
| // Returns 0 at end of traversal.
|
1186
|
+
| beqz CRET1, ->fff_restv // End of traversal: return nil.
|
1187
|
+
|. li CARG3, LJ_TNIL
|
1188
|
+
| ldc1 f0, 8(BASE) // Copy key and value to results.
|
1189
|
+
| addiu RA, BASE, -8
|
1190
|
+
| ldc1 f2, 16(BASE)
|
1191
|
+
| li RD, (2+1)*8
|
1192
|
+
| sdc1 f0, 0(RA)
|
1193
|
+
| b ->fff_res
|
1194
|
+
|. sdc1 f2, 8(RA)
|
1195
|
+
|
|
1196
|
+
|.ffunc_1 pairs
|
1197
|
+
| li AT, LJ_TTAB
|
1198
|
+
| bne CARG3, AT, ->fff_fallback
|
1199
|
+
|. lw PC, FRAME_PC(BASE)
|
1200
|
+
#if LJ_52
|
1201
|
+
| lw TAB:TMP2, TAB:CARG1->metatable
|
1202
|
+
| ldc1 f0, CFUNC:RB->upvalue[0]
|
1203
|
+
| bnez TAB:TMP2, ->fff_fallback
|
1204
|
+
#else
|
1205
|
+
| ldc1 f0, CFUNC:RB->upvalue[0]
|
1206
|
+
#endif
|
1207
|
+
|. addiu RA, BASE, -8
|
1208
|
+
| sw TISNIL, 8+HI(BASE)
|
1209
|
+
| li RD, (3+1)*8
|
1210
|
+
| b ->fff_res
|
1211
|
+
|. sdc1 f0, 0(RA)
|
1212
|
+
|
|
1213
|
+
|.ffunc ipairs_aux
|
1214
|
+
| sltiu AT, NARGS8:RC, 16
|
1215
|
+
| lw CARG3, HI(BASE)
|
1216
|
+
| lw TAB:CARG1, LO(BASE)
|
1217
|
+
| lw CARG4, 8+HI(BASE)
|
1218
|
+
| bnez AT, ->fff_fallback
|
1219
|
+
|. ldc1 FARG2, 8(BASE)
|
1220
|
+
| addiu CARG3, CARG3, -LJ_TTAB
|
1221
|
+
| sltiu AT, CARG4, LJ_TISNUM
|
1222
|
+
| li TMP0, 1
|
1223
|
+
| movn AT, r0, CARG3
|
1224
|
+
| mtc1 TMP0, FARG1
|
1225
|
+
| beqz AT, ->fff_fallback
|
1226
|
+
|. lw PC, FRAME_PC(BASE)
|
1227
|
+
| trunc.w.d FRET1, FARG2
|
1228
|
+
| cvt.d.w FARG1, FARG1
|
1229
|
+
| lw TMP0, TAB:CARG1->asize
|
1230
|
+
| lw TMP1, TAB:CARG1->array
|
1231
|
+
| mfc1 TMP2, FRET1
|
1232
|
+
| addiu RA, BASE, -8
|
1233
|
+
| add.d FARG2, FARG2, FARG1
|
1234
|
+
| addiu TMP2, TMP2, 1
|
1235
|
+
| sltu AT, TMP2, TMP0
|
1236
|
+
| sll TMP3, TMP2, 3
|
1237
|
+
| addu TMP3, TMP1, TMP3
|
1238
|
+
| beqz AT, >2 // Not in array part?
|
1239
|
+
|. sdc1 FARG2, 0(RA)
|
1240
|
+
| lw TMP2, HI(TMP3)
|
1241
|
+
| ldc1 f0, 0(TMP3)
|
1242
|
+
|1:
|
1243
|
+
| beq TMP2, TISNIL, ->fff_res // End of iteration, return 0 results.
|
1244
|
+
|. li RD, (0+1)*8
|
1245
|
+
| li RD, (2+1)*8
|
1246
|
+
| b ->fff_res
|
1247
|
+
|. sdc1 f0, 8(RA)
|
1248
|
+
|2: // Check for empty hash part first. Otherwise call C function.
|
1249
|
+
| lw TMP0, TAB:CARG1->hmask
|
1250
|
+
| load_got lj_tab_getinth
|
1251
|
+
| beqz TMP0, ->fff_res
|
1252
|
+
|. li RD, (0+1)*8
|
1253
|
+
| call_intern lj_tab_getinth // (GCtab *t, int32_t key)
|
1254
|
+
|. move CARG2, TMP2
|
1255
|
+
| // Returns cTValue * or NULL.
|
1256
|
+
| beqz CRET1, ->fff_res
|
1257
|
+
|. li RD, (0+1)*8
|
1258
|
+
| lw TMP2, HI(CRET1)
|
1259
|
+
| b <1
|
1260
|
+
|. ldc1 f0, 0(CRET1)
|
1261
|
+
|
|
1262
|
+
|.ffunc_1 ipairs
|
1263
|
+
| li AT, LJ_TTAB
|
1264
|
+
| bne CARG3, AT, ->fff_fallback
|
1265
|
+
|. lw PC, FRAME_PC(BASE)
|
1266
|
+
#if LJ_52
|
1267
|
+
| lw TAB:TMP2, TAB:CARG1->metatable
|
1268
|
+
| ldc1 f0, CFUNC:RB->upvalue[0]
|
1269
|
+
| bnez TAB:TMP2, ->fff_fallback
|
1270
|
+
#else
|
1271
|
+
| ldc1 f0, CFUNC:RB->upvalue[0]
|
1272
|
+
#endif
|
1273
|
+
|. addiu RA, BASE, -8
|
1274
|
+
| sw r0, 8+HI(BASE)
|
1275
|
+
| sw r0, 8+LO(BASE)
|
1276
|
+
| li RD, (3+1)*8
|
1277
|
+
| b ->fff_res
|
1278
|
+
|. sdc1 f0, 0(RA)
|
1279
|
+
|
|
1280
|
+
|//-- Base library: catch errors ----------------------------------------
|
1281
|
+
|
|
1282
|
+
|.ffunc pcall
|
1283
|
+
| lbu TMP3, DISPATCH_GL(hookmask)(DISPATCH)
|
1284
|
+
| beqz NARGS8:RC, ->fff_fallback
|
1285
|
+
| move TMP2, BASE
|
1286
|
+
| addiu BASE, BASE, 8
|
1287
|
+
| // Remember active hook before pcall.
|
1288
|
+
| srl TMP3, TMP3, HOOK_ACTIVE_SHIFT
|
1289
|
+
| andi TMP3, TMP3, 1
|
1290
|
+
| addiu PC, TMP3, 8+FRAME_PCALL
|
1291
|
+
| b ->vm_call_dispatch
|
1292
|
+
|. addiu NARGS8:RC, NARGS8:RC, -8
|
1293
|
+
|
|
1294
|
+
|.ffunc xpcall
|
1295
|
+
| sltiu AT, NARGS8:RC, 16
|
1296
|
+
| lw CARG4, 8+HI(BASE)
|
1297
|
+
| bnez AT, ->fff_fallback
|
1298
|
+
|. ldc1 FARG2, 8(BASE)
|
1299
|
+
| ldc1 FARG1, 0(BASE)
|
1300
|
+
| lbu TMP1, DISPATCH_GL(hookmask)(DISPATCH)
|
1301
|
+
| li AT, LJ_TFUNC
|
1302
|
+
| move TMP2, BASE
|
1303
|
+
| bne CARG4, AT, ->fff_fallback // Traceback must be a function.
|
1304
|
+
| addiu BASE, BASE, 16
|
1305
|
+
| // Remember active hook before pcall.
|
1306
|
+
| srl TMP3, TMP3, HOOK_ACTIVE_SHIFT
|
1307
|
+
| sdc1 FARG2, 0(TMP2) // Swap function and traceback.
|
1308
|
+
| andi TMP3, TMP3, 1
|
1309
|
+
| sdc1 FARG1, 8(TMP2)
|
1310
|
+
| addiu PC, TMP3, 16+FRAME_PCALL
|
1311
|
+
| b ->vm_call_dispatch
|
1312
|
+
|. addiu NARGS8:RC, NARGS8:RC, -16
|
1313
|
+
|
|
1314
|
+
|//-- Coroutine library --------------------------------------------------
|
1315
|
+
|
|
1316
|
+
|.macro coroutine_resume_wrap, resume
|
1317
|
+
|.if resume
|
1318
|
+
|.ffunc_1 coroutine_resume
|
1319
|
+
| li AT, LJ_TTHREAD
|
1320
|
+
| bne CARG3, AT, ->fff_fallback
|
1321
|
+
|.else
|
1322
|
+
|.ffunc coroutine_wrap_aux
|
1323
|
+
| lw L:CARG1, CFUNC:RB->upvalue[0].gcr
|
1324
|
+
|.endif
|
1325
|
+
| lbu TMP0, L:CARG1->status
|
1326
|
+
| lw TMP1, L:CARG1->cframe
|
1327
|
+
| lw CARG2, L:CARG1->top
|
1328
|
+
| lw TMP2, L:CARG1->base
|
1329
|
+
| addiu TMP3, TMP0, -LUA_YIELD
|
1330
|
+
| bgtz TMP3, ->fff_fallback // st > LUA_YIELD?
|
1331
|
+
|. xor TMP2, TMP2, CARG2
|
1332
|
+
| bnez TMP1, ->fff_fallback // cframe != 0?
|
1333
|
+
|. or AT, TMP2, TMP0
|
1334
|
+
| lw TMP0, L:CARG1->maxstack
|
1335
|
+
| beqz AT, ->fff_fallback // base == top && st == 0?
|
1336
|
+
|. lw PC, FRAME_PC(BASE)
|
1337
|
+
| addu TMP2, CARG2, NARGS8:RC
|
1338
|
+
| sltu AT, TMP0, TMP2
|
1339
|
+
| bnez AT, ->fff_fallback // Stack overflow?
|
1340
|
+
|. sw PC, SAVE_PC
|
1341
|
+
| sw BASE, L->base
|
1342
|
+
|1:
|
1343
|
+
|.if resume
|
1344
|
+
| addiu BASE, BASE, 8 // Keep resumed thread in stack for GC.
|
1345
|
+
| addiu NARGS8:RC, NARGS8:RC, -8
|
1346
|
+
| addiu TMP2, TMP2, -8
|
1347
|
+
|.endif
|
1348
|
+
| sw TMP2, L:CARG1->top
|
1349
|
+
| addu TMP1, BASE, NARGS8:RC
|
1350
|
+
| move CARG3, CARG2
|
1351
|
+
| sw BASE, L->top
|
1352
|
+
|2: // Move args to coroutine.
|
1353
|
+
| ldc1 f0, 0(BASE)
|
1354
|
+
| sltu AT, BASE, TMP1
|
1355
|
+
| beqz AT, >3
|
1356
|
+
|. addiu BASE, BASE, 8
|
1357
|
+
| sdc1 f0, 0(CARG3)
|
1358
|
+
| b <2
|
1359
|
+
|. addiu CARG3, CARG3, 8
|
1360
|
+
|3:
|
1361
|
+
| bal ->vm_resume // (lua_State *L, TValue *base, 0, 0)
|
1362
|
+
|. move L:RA, L:CARG1
|
1363
|
+
| // Returns thread status.
|
1364
|
+
|4:
|
1365
|
+
| lw TMP2, L:RA->base
|
1366
|
+
| sltiu AT, CRET1, LUA_YIELD+1
|
1367
|
+
| lw TMP3, L:RA->top
|
1368
|
+
| li_vmstate INTERP
|
1369
|
+
| lw BASE, L->base
|
1370
|
+
| sw L, DISPATCH_GL(cur_L)(DISPATCH)
|
1371
|
+
| st_vmstate
|
1372
|
+
| beqz AT, >8
|
1373
|
+
|. subu RD, TMP3, TMP2
|
1374
|
+
| lw TMP0, L->maxstack
|
1375
|
+
| beqz RD, >6 // No results?
|
1376
|
+
|. addu TMP1, BASE, RD
|
1377
|
+
| sltu AT, TMP0, TMP1
|
1378
|
+
| bnez AT, >9 // Need to grow stack?
|
1379
|
+
|. addu TMP3, TMP2, RD
|
1380
|
+
| sw TMP2, L:RA->top // Clear coroutine stack.
|
1381
|
+
| move TMP1, BASE
|
1382
|
+
|5: // Move results from coroutine.
|
1383
|
+
| ldc1 f0, 0(TMP2)
|
1384
|
+
| addiu TMP2, TMP2, 8
|
1385
|
+
| sltu AT, TMP2, TMP3
|
1386
|
+
| sdc1 f0, 0(TMP1)
|
1387
|
+
| bnez AT, <5
|
1388
|
+
|. addiu TMP1, TMP1, 8
|
1389
|
+
|6:
|
1390
|
+
| andi TMP0, PC, FRAME_TYPE
|
1391
|
+
|.if resume
|
1392
|
+
| li TMP1, LJ_TTRUE
|
1393
|
+
| addiu RA, BASE, -8
|
1394
|
+
| sw TMP1, -8+HI(BASE) // Prepend true to results.
|
1395
|
+
| addiu RD, RD, 16
|
1396
|
+
|.else
|
1397
|
+
| move RA, BASE
|
1398
|
+
| addiu RD, RD, 8
|
1399
|
+
|.endif
|
1400
|
+
|7:
|
1401
|
+
| sw PC, SAVE_PC
|
1402
|
+
| beqz TMP0, ->BC_RET_Z
|
1403
|
+
|. move MULTRES, RD
|
1404
|
+
| b ->vm_return
|
1405
|
+
|. nop
|
1406
|
+
|
|
1407
|
+
|8: // Coroutine returned with error (at co->top-1).
|
1408
|
+
|.if resume
|
1409
|
+
| addiu TMP3, TMP3, -8
|
1410
|
+
| li TMP1, LJ_TFALSE
|
1411
|
+
| ldc1 f0, 0(TMP3)
|
1412
|
+
| sw TMP3, L:RA->top // Remove error from coroutine stack.
|
1413
|
+
| li RD, (2+1)*8
|
1414
|
+
| sw TMP1, -8+HI(BASE) // Prepend false to results.
|
1415
|
+
| addiu RA, BASE, -8
|
1416
|
+
| sdc1 f0, 0(BASE) // Copy error message.
|
1417
|
+
| b <7
|
1418
|
+
|. andi TMP0, PC, FRAME_TYPE
|
1419
|
+
|.else
|
1420
|
+
| load_got lj_ffh_coroutine_wrap_err
|
1421
|
+
| move CARG2, L:RA
|
1422
|
+
| call_intern lj_ffh_coroutine_wrap_err // (lua_State *L, lua_State *co)
|
1423
|
+
|. move CARG1, L
|
1424
|
+
|.endif
|
1425
|
+
|
|
1426
|
+
|9: // Handle stack expansion on return from yield.
|
1427
|
+
| load_got lj_state_growstack
|
1428
|
+
| srl CARG2, RD, 3
|
1429
|
+
| call_intern lj_state_growstack // (lua_State *L, int n)
|
1430
|
+
|. move CARG1, L
|
1431
|
+
| b <4
|
1432
|
+
|. li CRET1, 0
|
1433
|
+
|.endmacro
|
1434
|
+
|
|
1435
|
+
| coroutine_resume_wrap 1 // coroutine.resume
|
1436
|
+
| coroutine_resume_wrap 0 // coroutine.wrap
|
1437
|
+
|
|
1438
|
+
|.ffunc coroutine_yield
|
1439
|
+
| lw TMP0, L->cframe
|
1440
|
+
| addu TMP1, BASE, NARGS8:RC
|
1441
|
+
| sw BASE, L->base
|
1442
|
+
| andi TMP0, TMP0, CFRAME_RESUME
|
1443
|
+
| sw TMP1, L->top
|
1444
|
+
| beqz TMP0, ->fff_fallback
|
1445
|
+
|. li CRET1, LUA_YIELD
|
1446
|
+
| sw r0, L->cframe
|
1447
|
+
| b ->vm_leave_unw
|
1448
|
+
|. sb CRET1, L->status
|
1449
|
+
|
|
1450
|
+
|//-- Math library -------------------------------------------------------
|
1451
|
+
|
|
1452
|
+
|.ffunc_n math_abs
|
1453
|
+
|. abs.d FRET1, FARG1
|
1454
|
+
|->fff_resn:
|
1455
|
+
| lw PC, FRAME_PC(BASE)
|
1456
|
+
| addiu RA, BASE, -8
|
1457
|
+
| b ->fff_res1
|
1458
|
+
|. sdc1 FRET1, -8(BASE)
|
1459
|
+
|
|
1460
|
+
|->fff_restv:
|
1461
|
+
| // CARG3/CARG1 = TValue result.
|
1462
|
+
| lw PC, FRAME_PC(BASE)
|
1463
|
+
| sw CARG3, -8+HI(BASE)
|
1464
|
+
| addiu RA, BASE, -8
|
1465
|
+
| sw CARG1, -8+LO(BASE)
|
1466
|
+
|->fff_res1:
|
1467
|
+
| // RA = results, PC = return.
|
1468
|
+
| li RD, (1+1)*8
|
1469
|
+
|->fff_res:
|
1470
|
+
| // RA = results, RD = (nresults+1)*8, PC = return.
|
1471
|
+
| andi TMP0, PC, FRAME_TYPE
|
1472
|
+
| bnez TMP0, ->vm_return
|
1473
|
+
|. move MULTRES, RD
|
1474
|
+
| lw INS, -4(PC)
|
1475
|
+
| decode_RB8a RB, INS
|
1476
|
+
| decode_RB8b RB
|
1477
|
+
|5:
|
1478
|
+
| sltu AT, RD, RB
|
1479
|
+
| bnez AT, >6 // More results expected?
|
1480
|
+
|. decode_RA8a TMP0, INS
|
1481
|
+
| decode_RA8b TMP0
|
1482
|
+
| ins_next1
|
1483
|
+
| // Adjust BASE. KBASE is assumed to be set for the calling frame.
|
1484
|
+
| subu BASE, RA, TMP0
|
1485
|
+
| ins_next2
|
1486
|
+
|
|
1487
|
+
|6: // Fill up results with nil.
|
1488
|
+
| addu TMP1, RA, RD
|
1489
|
+
| addiu RD, RD, 8
|
1490
|
+
| b <5
|
1491
|
+
|. sw TISNIL, -8+HI(TMP1)
|
1492
|
+
|
|
1493
|
+
|.macro math_extern, func
|
1494
|
+
|->ff_math_ .. func:
|
1495
|
+
| lw CARG3, HI(BASE)
|
1496
|
+
| beqz NARGS8:RC, ->fff_fallback
|
1497
|
+
|. load_got func
|
1498
|
+
| sltiu AT, CARG3, LJ_TISNUM
|
1499
|
+
| beqz AT, ->fff_fallback
|
1500
|
+
|. nop
|
1501
|
+
| call_extern
|
1502
|
+
|. ldc1 FARG1, 0(BASE)
|
1503
|
+
| b ->fff_resn
|
1504
|
+
|. nop
|
1505
|
+
|.endmacro
|
1506
|
+
|
|
1507
|
+
|.macro math_extern2, func
|
1508
|
+
| .ffunc_nn math_ .. func
|
1509
|
+
|. load_got func
|
1510
|
+
| call_extern
|
1511
|
+
|. nop
|
1512
|
+
| b ->fff_resn
|
1513
|
+
|. nop
|
1514
|
+
|.endmacro
|
1515
|
+
|
|
1516
|
+
|.macro math_round, func
|
1517
|
+
| .ffunc_n math_ .. func
|
1518
|
+
|. nop
|
1519
|
+
| bal ->vm_ .. func
|
1520
|
+
|. nop
|
1521
|
+
| b ->fff_resn
|
1522
|
+
|. nop
|
1523
|
+
|.endmacro
|
1524
|
+
|
|
1525
|
+
| math_round floor
|
1526
|
+
| math_round ceil
|
1527
|
+
|
|
1528
|
+
|.ffunc math_log
|
1529
|
+
| lw CARG3, HI(BASE)
|
1530
|
+
| li AT, 8
|
1531
|
+
| bne NARGS8:RC, AT, ->fff_fallback // Exactly 1 argument.
|
1532
|
+
|. load_got log
|
1533
|
+
| sltiu AT, CARG3, LJ_TISNUM
|
1534
|
+
| beqz AT, ->fff_fallback
|
1535
|
+
|. nop
|
1536
|
+
| call_extern
|
1537
|
+
|. ldc1 FARG1, 0(BASE)
|
1538
|
+
| b ->fff_resn
|
1539
|
+
|. nop
|
1540
|
+
|
|
1541
|
+
| math_extern log10
|
1542
|
+
| math_extern exp
|
1543
|
+
| math_extern sin
|
1544
|
+
| math_extern cos
|
1545
|
+
| math_extern tan
|
1546
|
+
| math_extern asin
|
1547
|
+
| math_extern acos
|
1548
|
+
| math_extern atan
|
1549
|
+
| math_extern sinh
|
1550
|
+
| math_extern cosh
|
1551
|
+
| math_extern tanh
|
1552
|
+
| math_extern2 pow
|
1553
|
+
| math_extern2 atan2
|
1554
|
+
| math_extern2 fmod
|
1555
|
+
|
|
1556
|
+
|.ffunc_n math_sqrt
|
1557
|
+
|. sqrt.d FRET1, FARG1
|
1558
|
+
| b ->fff_resn
|
1559
|
+
|. nop
|
1560
|
+
|
|
1561
|
+
|.ffunc_nn math_ldexp
|
1562
|
+
| trunc.w.d FARG2, FARG2
|
1563
|
+
| load_got ldexp
|
1564
|
+
| mfc1 CARG3, FARG2
|
1565
|
+
| call_extern
|
1566
|
+
|. nop
|
1567
|
+
| b ->fff_resn
|
1568
|
+
|. nop
|
1569
|
+
|
|
1570
|
+
|.ffunc_n math_frexp
|
1571
|
+
| load_got frexp
|
1572
|
+
| lw PC, FRAME_PC(BASE)
|
1573
|
+
| call_extern
|
1574
|
+
|. addiu CARG3, DISPATCH, DISPATCH_GL(tmptv)
|
1575
|
+
| lw TMP1, DISPATCH_GL(tmptv)(DISPATCH)
|
1576
|
+
| addiu RA, BASE, -8
|
1577
|
+
| mtc1 TMP1, FARG2
|
1578
|
+
| sdc1 FRET1, 0(RA)
|
1579
|
+
| cvt.d.w FARG2, FARG2
|
1580
|
+
| sdc1 FARG2, 8(RA)
|
1581
|
+
| b ->fff_res
|
1582
|
+
|. li RD, (2+1)*8
|
1583
|
+
|
|
1584
|
+
|.ffunc_n math_modf
|
1585
|
+
| load_got modf
|
1586
|
+
| lw PC, FRAME_PC(BASE)
|
1587
|
+
| call_extern
|
1588
|
+
|. addiu CARG3, BASE, -8
|
1589
|
+
| addiu RA, BASE, -8
|
1590
|
+
| sdc1 FRET1, 0(BASE)
|
1591
|
+
| b ->fff_res
|
1592
|
+
|. li RD, (2+1)*8
|
1593
|
+
|
|
1594
|
+
|.macro math_minmax, name, ismax
|
1595
|
+
|->ff_ .. name:
|
1596
|
+
| lw CARG3, HI(BASE)
|
1597
|
+
| beqz NARGS8:RC, ->fff_fallback
|
1598
|
+
|. ldc1 FRET1, 0(BASE)
|
1599
|
+
| sltiu AT, CARG3, LJ_TISNUM
|
1600
|
+
| beqz AT, ->fff_fallback
|
1601
|
+
|. addu TMP2, BASE, NARGS8:RC
|
1602
|
+
| addiu TMP1, BASE, 8
|
1603
|
+
| beq TMP1, TMP2, ->fff_resn
|
1604
|
+
|1:
|
1605
|
+
|. lw CARG3, HI(TMP1)
|
1606
|
+
| ldc1 FARG1, 0(TMP1)
|
1607
|
+
| addiu TMP1, TMP1, 8
|
1608
|
+
| sltiu AT, CARG3, LJ_TISNUM
|
1609
|
+
| beqz AT, ->fff_fallback
|
1610
|
+
|.if ismax
|
1611
|
+
|. c.olt.d FARG1, FRET1
|
1612
|
+
|.else
|
1613
|
+
|. c.olt.d FRET1, FARG1
|
1614
|
+
|.endif
|
1615
|
+
| bne TMP1, TMP2, <1
|
1616
|
+
|. movf.d FRET1, FARG1
|
1617
|
+
| b ->fff_resn
|
1618
|
+
|. nop
|
1619
|
+
|.endmacro
|
1620
|
+
|
|
1621
|
+
| math_minmax math_min, 0
|
1622
|
+
| math_minmax math_max, 1
|
1623
|
+
|
|
1624
|
+
|//-- String library -----------------------------------------------------
|
1625
|
+
|
|
1626
|
+
|.ffunc string_byte // Only handle the 1-arg case here.
|
1627
|
+
| lw CARG3, HI(BASE)
|
1628
|
+
| lw STR:CARG1, LO(BASE)
|
1629
|
+
| xori AT, NARGS8:RC, 8
|
1630
|
+
| addiu CARG3, CARG3, -LJ_TSTR
|
1631
|
+
| or AT, AT, CARG3
|
1632
|
+
| bnez AT, ->fff_fallback // Need exactly 1 string argument.
|
1633
|
+
|. nop
|
1634
|
+
| lw TMP0, STR:CARG1->len
|
1635
|
+
| lbu TMP1, STR:CARG1[1] // Access is always ok (NUL at end).
|
1636
|
+
| addiu RA, BASE, -8
|
1637
|
+
| sltu RD, r0, TMP0
|
1638
|
+
| mtc1 TMP1, f0
|
1639
|
+
| addiu RD, RD, 1
|
1640
|
+
| cvt.d.w f0, f0
|
1641
|
+
| lw PC, FRAME_PC(BASE)
|
1642
|
+
| sll RD, RD, 3 // RD = ((str->len != 0)+1)*8
|
1643
|
+
| b ->fff_res
|
1644
|
+
|. sdc1 f0, 0(RA)
|
1645
|
+
|
|
1646
|
+
|.ffunc string_char // Only handle the 1-arg case here.
|
1647
|
+
| ffgccheck
|
1648
|
+
| lw CARG3, HI(BASE)
|
1649
|
+
| ldc1 FARG1, 0(BASE)
|
1650
|
+
| li AT, 8
|
1651
|
+
| bne NARGS8:RC, AT, ->fff_fallback // Exactly 1 argument.
|
1652
|
+
|. sltiu AT, CARG3, LJ_TISNUM
|
1653
|
+
| beqz AT, ->fff_fallback
|
1654
|
+
|. li CARG3, 1
|
1655
|
+
| trunc.w.d FARG1, FARG1
|
1656
|
+
| addiu CARG2, sp, ARG5_OFS
|
1657
|
+
| sltiu AT, TMP0, 256
|
1658
|
+
| mfc1 TMP0, FARG1
|
1659
|
+
| beqz AT, ->fff_fallback
|
1660
|
+
|. sw TMP0, ARG5
|
1661
|
+
|->fff_newstr:
|
1662
|
+
| load_got lj_str_new
|
1663
|
+
| sw BASE, L->base
|
1664
|
+
| sw PC, SAVE_PC
|
1665
|
+
| call_intern lj_str_new // (lua_State *L, char *str, size_t l)
|
1666
|
+
|. move CARG1, L
|
1667
|
+
| // Returns GCstr *.
|
1668
|
+
| lw BASE, L->base
|
1669
|
+
|->fff_resstr:
|
1670
|
+
| move CARG1, CRET1
|
1671
|
+
| b ->fff_restv
|
1672
|
+
|. li CARG3, LJ_TSTR
|
1673
|
+
|
|
1674
|
+
|.ffunc string_sub
|
1675
|
+
| ffgccheck
|
1676
|
+
| addiu AT, NARGS8:RC, -16
|
1677
|
+
| lw CARG3, 16+HI(BASE)
|
1678
|
+
| ldc1 f0, 16(BASE)
|
1679
|
+
| lw TMP0, HI(BASE)
|
1680
|
+
| lw STR:CARG1, LO(BASE)
|
1681
|
+
| bltz AT, ->fff_fallback
|
1682
|
+
| lw CARG2, 8+HI(BASE)
|
1683
|
+
| ldc1 f2, 8(BASE)
|
1684
|
+
| beqz AT, >1
|
1685
|
+
|. li CARG4, -1
|
1686
|
+
| trunc.w.d f0, f0
|
1687
|
+
| sltiu AT, CARG3, LJ_TISNUM
|
1688
|
+
| beqz AT, ->fff_fallback
|
1689
|
+
|. mfc1 CARG4, f0
|
1690
|
+
|1:
|
1691
|
+
| sltiu AT, CARG2, LJ_TISNUM
|
1692
|
+
| beqz AT, ->fff_fallback
|
1693
|
+
|. li AT, LJ_TSTR
|
1694
|
+
| trunc.w.d f2, f2
|
1695
|
+
| bne TMP0, AT, ->fff_fallback
|
1696
|
+
|. lw CARG2, STR:CARG1->len
|
1697
|
+
| mfc1 CARG3, f2
|
1698
|
+
| // STR:CARG1 = str, CARG2 = str->len, CARG3 = start, CARG4 = end
|
1699
|
+
| slt AT, CARG4, r0
|
1700
|
+
| addiu TMP0, CARG2, 1
|
1701
|
+
| addu TMP1, CARG4, TMP0
|
1702
|
+
| slt TMP3, CARG3, r0
|
1703
|
+
| movn CARG4, TMP1, AT // if (end < 0) end += len+1
|
1704
|
+
| addu TMP1, CARG3, TMP0
|
1705
|
+
| movn CARG3, TMP1, TMP3 // if (start < 0) start += len+1
|
1706
|
+
| li TMP2, 1
|
1707
|
+
| slt AT, CARG4, r0
|
1708
|
+
| slt TMP3, r0, CARG3
|
1709
|
+
| movn CARG4, r0, AT // if (end < 0) end = 0
|
1710
|
+
| movz CARG3, TMP2, TMP3 // if (start < 1) start = 1
|
1711
|
+
| slt AT, CARG2, CARG4
|
1712
|
+
| movn CARG4, CARG2, AT // if (end > len) end = len
|
1713
|
+
| addu CARG2, STR:CARG1, CARG3
|
1714
|
+
| subu CARG3, CARG4, CARG3 // len = end - start
|
1715
|
+
| addiu CARG2, CARG2, sizeof(GCstr)-1
|
1716
|
+
| bgez CARG3, ->fff_newstr
|
1717
|
+
|. addiu CARG3, CARG3, 1 // len++
|
1718
|
+
|->fff_emptystr: // Return empty string.
|
1719
|
+
| addiu STR:CARG1, DISPATCH, DISPATCH_GL(strempty)
|
1720
|
+
| b ->fff_restv
|
1721
|
+
|. li CARG3, LJ_TSTR
|
1722
|
+
|
|
1723
|
+
|.macro ffstring_op, name
|
1724
|
+
| .ffunc string_ .. name
|
1725
|
+
| ffgccheck
|
1726
|
+
| lw CARG3, HI(BASE)
|
1727
|
+
| lw STR:CARG2, LO(BASE)
|
1728
|
+
| beqz NARGS8:RC, ->fff_fallback
|
1729
|
+
|. li AT, LJ_TSTR
|
1730
|
+
| bne CARG3, AT, ->fff_fallback
|
1731
|
+
|. addiu SBUF:CARG1, DISPATCH, DISPATCH_GL(tmpbuf)
|
1732
|
+
| load_got lj_buf_putstr_ .. name
|
1733
|
+
| lw TMP0, SBUF:CARG1->b
|
1734
|
+
| sw L, SBUF:CARG1->L
|
1735
|
+
| sw BASE, L->base
|
1736
|
+
| sw TMP0, SBUF:CARG1->p
|
1737
|
+
| call_intern extern lj_buf_putstr_ .. name
|
1738
|
+
|. sw PC, SAVE_PC
|
1739
|
+
| load_got lj_buf_tostr
|
1740
|
+
| call_intern lj_buf_tostr
|
1741
|
+
|. move SBUF:CARG1, SBUF:CRET1
|
1742
|
+
| b ->fff_resstr
|
1743
|
+
|. lw BASE, L->base
|
1744
|
+
|.endmacro
|
1745
|
+
|
|
1746
|
+
|ffstring_op reverse
|
1747
|
+
|ffstring_op lower
|
1748
|
+
|ffstring_op upper
|
1749
|
+
|
|
1750
|
+
|//-- Bit library --------------------------------------------------------
|
1751
|
+
|
|
1752
|
+
|.macro .ffunc_bit, name
|
1753
|
+
| .ffunc_n bit_..name
|
1754
|
+
|. add.d FARG1, FARG1, TOBIT
|
1755
|
+
| mfc1 CRET1, FARG1
|
1756
|
+
|.endmacro
|
1757
|
+
|
|
1758
|
+
|.macro .ffunc_bit_op, name, ins
|
1759
|
+
| .ffunc_bit name
|
1760
|
+
| addiu TMP1, BASE, 8
|
1761
|
+
| addu TMP2, BASE, NARGS8:RC
|
1762
|
+
|1:
|
1763
|
+
| lw CARG4, HI(TMP1)
|
1764
|
+
| beq TMP1, TMP2, ->fff_resi
|
1765
|
+
|. ldc1 FARG1, 0(TMP1)
|
1766
|
+
| sltiu AT, CARG4, LJ_TISNUM
|
1767
|
+
| beqz AT, ->fff_fallback
|
1768
|
+
| add.d FARG1, FARG1, TOBIT
|
1769
|
+
| mfc1 CARG2, FARG1
|
1770
|
+
| ins CRET1, CRET1, CARG2
|
1771
|
+
| b <1
|
1772
|
+
|. addiu TMP1, TMP1, 8
|
1773
|
+
|.endmacro
|
1774
|
+
|
|
1775
|
+
|.ffunc_bit_op band, and
|
1776
|
+
|.ffunc_bit_op bor, or
|
1777
|
+
|.ffunc_bit_op bxor, xor
|
1778
|
+
|
|
1779
|
+
|.ffunc_bit bswap
|
1780
|
+
| srl TMP0, CRET1, 24
|
1781
|
+
| srl TMP2, CRET1, 8
|
1782
|
+
| sll TMP1, CRET1, 24
|
1783
|
+
| andi TMP2, TMP2, 0xff00
|
1784
|
+
| or TMP0, TMP0, TMP1
|
1785
|
+
| andi CRET1, CRET1, 0xff00
|
1786
|
+
| or TMP0, TMP0, TMP2
|
1787
|
+
| sll CRET1, CRET1, 8
|
1788
|
+
| b ->fff_resi
|
1789
|
+
|. or CRET1, TMP0, CRET1
|
1790
|
+
|
|
1791
|
+
|.ffunc_bit bnot
|
1792
|
+
| b ->fff_resi
|
1793
|
+
|. not CRET1, CRET1
|
1794
|
+
|
|
1795
|
+
|.macro .ffunc_bit_sh, name, ins, shmod
|
1796
|
+
| .ffunc_nn bit_..name
|
1797
|
+
|. add.d FARG1, FARG1, TOBIT
|
1798
|
+
| add.d FARG2, FARG2, TOBIT
|
1799
|
+
| mfc1 CARG1, FARG1
|
1800
|
+
| mfc1 CARG2, FARG2
|
1801
|
+
|.if shmod == 1
|
1802
|
+
| li AT, 32
|
1803
|
+
| subu TMP0, AT, CARG2
|
1804
|
+
| sllv CARG2, CARG1, CARG2
|
1805
|
+
| srlv CARG1, CARG1, TMP0
|
1806
|
+
|.elif shmod == 2
|
1807
|
+
| li AT, 32
|
1808
|
+
| subu TMP0, AT, CARG2
|
1809
|
+
| srlv CARG2, CARG1, CARG2
|
1810
|
+
| sllv CARG1, CARG1, TMP0
|
1811
|
+
|.endif
|
1812
|
+
| b ->fff_resi
|
1813
|
+
|. ins CRET1, CARG1, CARG2
|
1814
|
+
|.endmacro
|
1815
|
+
|
|
1816
|
+
|.ffunc_bit_sh lshift, sllv, 0
|
1817
|
+
|.ffunc_bit_sh rshift, srlv, 0
|
1818
|
+
|.ffunc_bit_sh arshift, srav, 0
|
1819
|
+
|// Can't use rotrv, since it's only in MIPS32R2.
|
1820
|
+
|.ffunc_bit_sh rol, or, 1
|
1821
|
+
|.ffunc_bit_sh ror, or, 2
|
1822
|
+
|
|
1823
|
+
|.ffunc_bit tobit
|
1824
|
+
|->fff_resi:
|
1825
|
+
| mtc1 CRET1, FRET1
|
1826
|
+
| b ->fff_resn
|
1827
|
+
|. cvt.d.w FRET1, FRET1
|
1828
|
+
|
|
1829
|
+
|//-----------------------------------------------------------------------
|
1830
|
+
|
|
1831
|
+
|->fff_fallback: // Call fast function fallback handler.
|
1832
|
+
| // BASE = new base, RB = CFUNC, RC = nargs*8
|
1833
|
+
| lw TMP3, CFUNC:RB->f
|
1834
|
+
| addu TMP1, BASE, NARGS8:RC
|
1835
|
+
| lw PC, FRAME_PC(BASE) // Fallback may overwrite PC.
|
1836
|
+
| addiu TMP0, TMP1, 8*LUA_MINSTACK
|
1837
|
+
| lw TMP2, L->maxstack
|
1838
|
+
| sw PC, SAVE_PC // Redundant (but a defined value).
|
1839
|
+
| sltu AT, TMP2, TMP0
|
1840
|
+
| sw BASE, L->base
|
1841
|
+
| sw TMP1, L->top
|
1842
|
+
| bnez AT, >5 // Need to grow stack.
|
1843
|
+
|. move CFUNCADDR, TMP3
|
1844
|
+
| jalr TMP3 // (lua_State *L)
|
1845
|
+
|. move CARG1, L
|
1846
|
+
| // Either throws an error, or recovers and returns -1, 0 or nresults+1.
|
1847
|
+
| lw BASE, L->base
|
1848
|
+
| sll RD, CRET1, 3
|
1849
|
+
| bgtz CRET1, ->fff_res // Returned nresults+1?
|
1850
|
+
|. addiu RA, BASE, -8
|
1851
|
+
|1: // Returned 0 or -1: retry fast path.
|
1852
|
+
| lw TMP0, L->top
|
1853
|
+
| lw LFUNC:RB, FRAME_FUNC(BASE)
|
1854
|
+
| bnez CRET1, ->vm_call_tail // Returned -1?
|
1855
|
+
|. subu NARGS8:RC, TMP0, BASE
|
1856
|
+
| ins_callt // Returned 0: retry fast path.
|
1857
|
+
|
|
1858
|
+
|// Reconstruct previous base for vmeta_call during tailcall.
|
1859
|
+
|->vm_call_tail:
|
1860
|
+
| andi TMP0, PC, FRAME_TYPE
|
1861
|
+
| li AT, -4
|
1862
|
+
| bnez TMP0, >3
|
1863
|
+
|. and TMP1, PC, AT
|
1864
|
+
| lbu TMP1, OFS_RA(PC)
|
1865
|
+
| sll TMP1, TMP1, 3
|
1866
|
+
| addiu TMP1, TMP1, 8
|
1867
|
+
|3:
|
1868
|
+
| b ->vm_call_dispatch // Resolve again for tailcall.
|
1869
|
+
|. subu TMP2, BASE, TMP1
|
1870
|
+
|
|
1871
|
+
|5: // Grow stack for fallback handler.
|
1872
|
+
| load_got lj_state_growstack
|
1873
|
+
| li CARG2, LUA_MINSTACK
|
1874
|
+
| call_intern lj_state_growstack // (lua_State *L, int n)
|
1875
|
+
|. move CARG1, L
|
1876
|
+
| lw BASE, L->base
|
1877
|
+
| b <1
|
1878
|
+
|. li CRET1, 0 // Force retry.
|
1879
|
+
|
|
1880
|
+
|->fff_gcstep: // Call GC step function.
|
1881
|
+
| // BASE = new base, RC = nargs*8
|
1882
|
+
| move MULTRES, ra
|
1883
|
+
| load_got lj_gc_step
|
1884
|
+
| sw BASE, L->base
|
1885
|
+
| addu TMP0, BASE, NARGS8:RC
|
1886
|
+
| sw PC, SAVE_PC // Redundant (but a defined value).
|
1887
|
+
| sw TMP0, L->top
|
1888
|
+
| call_intern lj_gc_step // (lua_State *L)
|
1889
|
+
|. move CARG1, L
|
1890
|
+
| lw BASE, L->base
|
1891
|
+
| move ra, MULTRES
|
1892
|
+
| lw TMP0, L->top
|
1893
|
+
| lw CFUNC:RB, FRAME_FUNC(BASE)
|
1894
|
+
| jr ra
|
1895
|
+
|. subu NARGS8:RC, TMP0, BASE
|
1896
|
+
|
|
1897
|
+
|//-----------------------------------------------------------------------
|
1898
|
+
|//-- Special dispatch targets -------------------------------------------
|
1899
|
+
|//-----------------------------------------------------------------------
|
1900
|
+
|
|
1901
|
+
|->vm_record: // Dispatch target for recording phase.
|
1902
|
+
|.if JIT
|
1903
|
+
| lbu TMP3, DISPATCH_GL(hookmask)(DISPATCH)
|
1904
|
+
| andi AT, TMP3, HOOK_VMEVENT // No recording while in vmevent.
|
1905
|
+
| bnez AT, >5
|
1906
|
+
| // Decrement the hookcount for consistency, but always do the call.
|
1907
|
+
|. lw TMP2, DISPATCH_GL(hookcount)(DISPATCH)
|
1908
|
+
| andi AT, TMP3, HOOK_ACTIVE
|
1909
|
+
| bnez AT, >1
|
1910
|
+
|. addiu TMP2, TMP2, -1
|
1911
|
+
| andi AT, TMP3, LUA_MASKLINE|LUA_MASKCOUNT
|
1912
|
+
| beqz AT, >1
|
1913
|
+
|. nop
|
1914
|
+
| b >1
|
1915
|
+
|. sw TMP2, DISPATCH_GL(hookcount)(DISPATCH)
|
1916
|
+
|.endif
|
1917
|
+
|
|
1918
|
+
|->vm_rethook: // Dispatch target for return hooks.
|
1919
|
+
| lbu TMP3, DISPATCH_GL(hookmask)(DISPATCH)
|
1920
|
+
| andi AT, TMP3, HOOK_ACTIVE // Hook already active?
|
1921
|
+
| beqz AT, >1
|
1922
|
+
|5: // Re-dispatch to static ins.
|
1923
|
+
|. lw AT, GG_DISP2STATIC(TMP0) // Assumes TMP0 holds DISPATCH+OP*4.
|
1924
|
+
| jr AT
|
1925
|
+
|. nop
|
1926
|
+
|
|
1927
|
+
|->vm_inshook: // Dispatch target for instr/line hooks.
|
1928
|
+
| lbu TMP3, DISPATCH_GL(hookmask)(DISPATCH)
|
1929
|
+
| lw TMP2, DISPATCH_GL(hookcount)(DISPATCH)
|
1930
|
+
| andi AT, TMP3, HOOK_ACTIVE // Hook already active?
|
1931
|
+
| bnez AT, <5
|
1932
|
+
|. andi AT, TMP3, LUA_MASKLINE|LUA_MASKCOUNT
|
1933
|
+
| beqz AT, <5
|
1934
|
+
|. addiu TMP2, TMP2, -1
|
1935
|
+
| beqz TMP2, >1
|
1936
|
+
|. sw TMP2, DISPATCH_GL(hookcount)(DISPATCH)
|
1937
|
+
| andi AT, TMP3, LUA_MASKLINE
|
1938
|
+
| beqz AT, <5
|
1939
|
+
|1:
|
1940
|
+
|. load_got lj_dispatch_ins
|
1941
|
+
| sw MULTRES, SAVE_MULTRES
|
1942
|
+
| move CARG2, PC
|
1943
|
+
| sw BASE, L->base
|
1944
|
+
| // SAVE_PC must hold the _previous_ PC. The callee updates it with PC.
|
1945
|
+
| call_intern lj_dispatch_ins // (lua_State *L, const BCIns *pc)
|
1946
|
+
|. move CARG1, L
|
1947
|
+
|3:
|
1948
|
+
| lw BASE, L->base
|
1949
|
+
|4: // Re-dispatch to static ins.
|
1950
|
+
| lw INS, -4(PC)
|
1951
|
+
| decode_OP4a TMP1, INS
|
1952
|
+
| decode_OP4b TMP1
|
1953
|
+
| addu TMP0, DISPATCH, TMP1
|
1954
|
+
| decode_RD8a RD, INS
|
1955
|
+
| lw AT, GG_DISP2STATIC(TMP0)
|
1956
|
+
| decode_RA8a RA, INS
|
1957
|
+
| decode_RD8b RD
|
1958
|
+
| jr AT
|
1959
|
+
| decode_RA8b RA
|
1960
|
+
|
|
1961
|
+
|->cont_hook: // Continue from hook yield.
|
1962
|
+
| addiu PC, PC, 4
|
1963
|
+
| b <4
|
1964
|
+
|. lw MULTRES, -24+LO(RB) // Restore MULTRES for *M ins.
|
1965
|
+
|
|
1966
|
+
|->vm_hotloop: // Hot loop counter underflow.
|
1967
|
+
|.if JIT
|
1968
|
+
| lw LFUNC:TMP1, FRAME_FUNC(BASE)
|
1969
|
+
| addiu CARG1, DISPATCH, GG_DISP2J
|
1970
|
+
| sw PC, SAVE_PC
|
1971
|
+
| lw TMP1, LFUNC:TMP1->pc
|
1972
|
+
| move CARG2, PC
|
1973
|
+
| sw L, DISPATCH_J(L)(DISPATCH)
|
1974
|
+
| lbu TMP1, PC2PROTO(framesize)(TMP1)
|
1975
|
+
| load_got lj_trace_hot
|
1976
|
+
| sw BASE, L->base
|
1977
|
+
| sll TMP1, TMP1, 3
|
1978
|
+
| addu TMP1, BASE, TMP1
|
1979
|
+
| call_intern lj_trace_hot // (jit_State *J, const BCIns *pc)
|
1980
|
+
|. sw TMP1, L->top
|
1981
|
+
| b <3
|
1982
|
+
|. nop
|
1983
|
+
|.endif
|
1984
|
+
|
|
1985
|
+
|->vm_callhook: // Dispatch target for call hooks.
|
1986
|
+
|.if JIT
|
1987
|
+
| b >1
|
1988
|
+
|.endif
|
1989
|
+
|. move CARG2, PC
|
1990
|
+
|
|
1991
|
+
|->vm_hotcall: // Hot call counter underflow.
|
1992
|
+
|.if JIT
|
1993
|
+
| ori CARG2, PC, 1
|
1994
|
+
|1:
|
1995
|
+
|.endif
|
1996
|
+
| load_got lj_dispatch_call
|
1997
|
+
| addu TMP0, BASE, RC
|
1998
|
+
| sw PC, SAVE_PC
|
1999
|
+
| sw BASE, L->base
|
2000
|
+
| subu RA, RA, BASE
|
2001
|
+
| sw TMP0, L->top
|
2002
|
+
| call_intern lj_dispatch_call // (lua_State *L, const BCIns *pc)
|
2003
|
+
|. move CARG1, L
|
2004
|
+
| // Returns ASMFunction.
|
2005
|
+
| lw BASE, L->base
|
2006
|
+
| lw TMP0, L->top
|
2007
|
+
| sw r0, SAVE_PC // Invalidate for subsequent line hook.
|
2008
|
+
| subu NARGS8:RC, TMP0, BASE
|
2009
|
+
| addu RA, BASE, RA
|
2010
|
+
| lw LFUNC:RB, FRAME_FUNC(BASE)
|
2011
|
+
| jr CRET1
|
2012
|
+
|. lw INS, -4(PC)
|
2013
|
+
|
|
2014
|
+
|->cont_stitch: // Trace stitching.
|
2015
|
+
|.if JIT
|
2016
|
+
| // RA = resultptr, RB = meta base
|
2017
|
+
| lw INS, -4(PC)
|
2018
|
+
| lw TMP3, -24+LO(RB) // Save previous trace number.
|
2019
|
+
| decode_RA8a RC, INS
|
2020
|
+
| addiu AT, MULTRES, -8
|
2021
|
+
| decode_RA8b RC
|
2022
|
+
| beqz AT, >2
|
2023
|
+
|. addu RC, BASE, RC // Call base.
|
2024
|
+
|1: // Move results down.
|
2025
|
+
| ldc1 f0, 0(RA)
|
2026
|
+
| addiu AT, AT, -8
|
2027
|
+
| addiu RA, RA, 8
|
2028
|
+
| sdc1 f0, 0(RC)
|
2029
|
+
| bnez AT, <1
|
2030
|
+
|. addiu RC, RC, 8
|
2031
|
+
|2:
|
2032
|
+
| decode_RA8a RA, INS
|
2033
|
+
| decode_RB8a RB, INS
|
2034
|
+
| decode_RA8b RA
|
2035
|
+
| decode_RB8b RB
|
2036
|
+
| addu RA, RA, RB
|
2037
|
+
| lw TMP1, DISPATCH_J(trace)(DISPATCH)
|
2038
|
+
| addu RA, BASE, RA
|
2039
|
+
|3:
|
2040
|
+
| sltu AT, RC, RA
|
2041
|
+
| bnez AT, >9 // More results wanted?
|
2042
|
+
|. sll TMP2, TMP3, 2
|
2043
|
+
|
|
2044
|
+
| addu TMP2, TMP1, TMP2
|
2045
|
+
| lw TRACE:TMP2, 0(TMP2)
|
2046
|
+
| beqz TRACE:TMP2, ->cont_nop
|
2047
|
+
|. nop
|
2048
|
+
| lhu RD, TRACE:TMP2->link
|
2049
|
+
| beq RD, TMP3, ->cont_nop // Blacklisted.
|
2050
|
+
|. load_got lj_dispatch_stitch
|
2051
|
+
| bnez RD, =>BC_JLOOP // Jump to stitched trace.
|
2052
|
+
|. sll RD, RD, 3
|
2053
|
+
|
|
2054
|
+
| // Stitch a new trace to the previous trace.
|
2055
|
+
| sw TMP3, DISPATCH_J(exitno)(DISPATCH)
|
2056
|
+
| sw L, DISPATCH_J(L)(DISPATCH)
|
2057
|
+
| sw BASE, L->base
|
2058
|
+
| addiu CARG1, DISPATCH, GG_DISP2J
|
2059
|
+
| call_intern lj_dispatch_stitch // (jit_State *J, const BCIns *pc)
|
2060
|
+
|. move CARG2, PC
|
2061
|
+
| b ->cont_nop
|
2062
|
+
|. lw BASE, L->base
|
2063
|
+
|
|
2064
|
+
|9:
|
2065
|
+
| sw TISNIL, HI(RC)
|
2066
|
+
| b <3
|
2067
|
+
|. addiu RC, RC, 8
|
2068
|
+
|.endif
|
2069
|
+
|
|
2070
|
+
|->vm_profhook: // Dispatch target for profiler hook.
|
2071
|
+
#if LJ_HASPROFILE
|
2072
|
+
| load_got lj_dispatch_profile
|
2073
|
+
| sw MULTRES, SAVE_MULTRES
|
2074
|
+
| move CARG2, PC
|
2075
|
+
| sw BASE, L->base
|
2076
|
+
| call_intern lj_dispatch_profile // (lua_State *L, const BCIns *pc)
|
2077
|
+
|. move CARG1, L
|
2078
|
+
| // HOOK_PROFILE is off again, so re-dispatch to dynamic instruction.
|
2079
|
+
| addiu PC, PC, -4
|
2080
|
+
| b ->cont_nop
|
2081
|
+
|. lw BASE, L->base
|
2082
|
+
#endif
|
2083
|
+
|
|
2084
|
+
|//-----------------------------------------------------------------------
|
2085
|
+
|//-- Trace exit handler -------------------------------------------------
|
2086
|
+
|//-----------------------------------------------------------------------
|
2087
|
+
|
|
2088
|
+
|.macro savex_, a, b
|
2089
|
+
| sdc1 f..a, 16+a*8(sp)
|
2090
|
+
| sw r..a, 16+32*8+a*4(sp)
|
2091
|
+
| sw r..b, 16+32*8+b*4(sp)
|
2092
|
+
|.endmacro
|
2093
|
+
|
|
2094
|
+
|->vm_exit_handler:
|
2095
|
+
|.if JIT
|
2096
|
+
| addiu sp, sp, -(16+32*8+32*4)
|
2097
|
+
| savex_ 0, 1
|
2098
|
+
| savex_ 2, 3
|
2099
|
+
| savex_ 4, 5
|
2100
|
+
| savex_ 6, 7
|
2101
|
+
| savex_ 8, 9
|
2102
|
+
| savex_ 10, 11
|
2103
|
+
| savex_ 12, 13
|
2104
|
+
| savex_ 14, 15
|
2105
|
+
| savex_ 16, 17
|
2106
|
+
| savex_ 18, 19
|
2107
|
+
| savex_ 20, 21
|
2108
|
+
| savex_ 22, 23
|
2109
|
+
| savex_ 24, 25
|
2110
|
+
| savex_ 26, 27
|
2111
|
+
| sdc1 f28, 16+28*8(sp)
|
2112
|
+
| sw r28, 16+32*8+28*4(sp)
|
2113
|
+
| sdc1 f30, 16+30*8(sp)
|
2114
|
+
| sw r30, 16+32*8+30*4(sp)
|
2115
|
+
| sw r0, 16+32*8+31*4(sp) // Clear RID_TMP.
|
2116
|
+
| li_vmstate EXIT
|
2117
|
+
| addiu TMP2, sp, 16+32*8+32*4 // Recompute original value of sp.
|
2118
|
+
| addiu DISPATCH, JGL, -GG_DISP2G-32768
|
2119
|
+
| lw TMP1, 0(TMP2) // Load exit number.
|
2120
|
+
| st_vmstate
|
2121
|
+
| sw TMP2, 16+32*8+29*4(sp) // Store sp in RID_SP.
|
2122
|
+
| lw L, DISPATCH_GL(cur_L)(DISPATCH)
|
2123
|
+
| lw BASE, DISPATCH_GL(jit_base)(DISPATCH)
|
2124
|
+
| load_got lj_trace_exit
|
2125
|
+
| sw L, DISPATCH_J(L)(DISPATCH)
|
2126
|
+
| sw ra, DISPATCH_J(parent)(DISPATCH) // Store trace number.
|
2127
|
+
| sw BASE, L->base
|
2128
|
+
| sw TMP1, DISPATCH_J(exitno)(DISPATCH) // Store exit number.
|
2129
|
+
| addiu CARG1, DISPATCH, GG_DISP2J
|
2130
|
+
| sw r0, DISPATCH_GL(jit_base)(DISPATCH)
|
2131
|
+
| call_intern lj_trace_exit // (jit_State *J, ExitState *ex)
|
2132
|
+
|. addiu CARG2, sp, 16
|
2133
|
+
| // Returns MULTRES (unscaled) or negated error code.
|
2134
|
+
| lw TMP1, L->cframe
|
2135
|
+
| li AT, -4
|
2136
|
+
| lw BASE, L->base
|
2137
|
+
| and sp, TMP1, AT
|
2138
|
+
| lw PC, SAVE_PC // Get SAVE_PC.
|
2139
|
+
| b >1
|
2140
|
+
|. sw L, SAVE_L // Set SAVE_L (on-trace resume/yield).
|
2141
|
+
|.endif
|
2142
|
+
|->vm_exit_interp:
|
2143
|
+
|.if JIT
|
2144
|
+
| // CRET1 = MULTRES or negated error code, BASE, PC and JGL set.
|
2145
|
+
| lw L, SAVE_L
|
2146
|
+
| addiu DISPATCH, JGL, -GG_DISP2G-32768
|
2147
|
+
| sw BASE, L->base
|
2148
|
+
|1:
|
2149
|
+
| bltz CRET1, >9 // Check for error from exit.
|
2150
|
+
|. lw LFUNC:RB, FRAME_FUNC(BASE)
|
2151
|
+
| lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
|
2152
|
+
| sll MULTRES, CRET1, 3
|
2153
|
+
| li TISNIL, LJ_TNIL
|
2154
|
+
| sw MULTRES, SAVE_MULTRES
|
2155
|
+
| mtc1 TMP3, TOBIT
|
2156
|
+
| lw TMP1, LFUNC:RB->pc
|
2157
|
+
| sw r0, DISPATCH_GL(jit_base)(DISPATCH)
|
2158
|
+
| lw KBASE, PC2PROTO(k)(TMP1)
|
2159
|
+
| cvt.d.s TOBIT, TOBIT
|
2160
|
+
| // Modified copy of ins_next which handles function header dispatch, too.
|
2161
|
+
| lw INS, 0(PC)
|
2162
|
+
| addiu PC, PC, 4
|
2163
|
+
| // Assumes TISNIL == ~LJ_VMST_INTERP == -1
|
2164
|
+
| sw TISNIL, DISPATCH_GL(vmstate)(DISPATCH)
|
2165
|
+
| decode_OP4a TMP1, INS
|
2166
|
+
| decode_OP4b TMP1
|
2167
|
+
| sltiu TMP2, TMP1, BC_FUNCF*4 // Function header?
|
2168
|
+
| addu TMP0, DISPATCH, TMP1
|
2169
|
+
| decode_RD8a RD, INS
|
2170
|
+
| lw AT, 0(TMP0)
|
2171
|
+
| decode_RA8a RA, INS
|
2172
|
+
| beqz TMP2, >2
|
2173
|
+
|. decode_RA8b RA
|
2174
|
+
| jr AT
|
2175
|
+
|. decode_RD8b RD
|
2176
|
+
|2:
|
2177
|
+
| sltiu TMP2, TMP1, (BC_FUNCC+2)*4 // Fast function?
|
2178
|
+
| bnez TMP2, >3
|
2179
|
+
|. lw TMP1, FRAME_PC(BASE)
|
2180
|
+
| // Check frame below fast function.
|
2181
|
+
| andi TMP0, TMP1, FRAME_TYPE
|
2182
|
+
| bnez TMP0, >3 // Trace stitching continuation?
|
2183
|
+
|. nop
|
2184
|
+
| // Otherwise set KBASE for Lua function below fast function.
|
2185
|
+
| lw TMP2, -4(TMP1)
|
2186
|
+
| decode_RA8a TMP0, TMP2
|
2187
|
+
| decode_RA8b TMP0
|
2188
|
+
| subu TMP1, BASE, TMP0
|
2189
|
+
| lw LFUNC:TMP2, -8+FRAME_FUNC(TMP1)
|
2190
|
+
| lw TMP1, LFUNC:TMP2->pc
|
2191
|
+
| lw KBASE, PC2PROTO(k)(TMP1)
|
2192
|
+
|3:
|
2193
|
+
| addiu RC, MULTRES, -8
|
2194
|
+
| jr AT
|
2195
|
+
|. addu RA, RA, BASE
|
2196
|
+
|
|
2197
|
+
|9: // Rethrow error from the right C frame.
|
2198
|
+
| load_got lj_err_throw
|
2199
|
+
| negu CARG2, CRET1
|
2200
|
+
| call_intern lj_err_throw // (lua_State *L, int errcode)
|
2201
|
+
|. move CARG1, L
|
2202
|
+
|.endif
|
2203
|
+
|
|
2204
|
+
|//-----------------------------------------------------------------------
|
2205
|
+
|//-- Math helper functions ----------------------------------------------
|
2206
|
+
|//-----------------------------------------------------------------------
|
2207
|
+
|
|
2208
|
+
|// Modifies AT, TMP0, FRET1, FRET2, f4. Keeps all others incl. FARG1.
|
2209
|
+
|.macro vm_round, func
|
2210
|
+
| lui TMP0, 0x4330 // Hiword of 2^52 (double).
|
2211
|
+
| mtc1 r0, f4
|
2212
|
+
| mtc1 TMP0, f5
|
2213
|
+
| abs.d FRET2, FARG1 // |x|
|
2214
|
+
| mfc1 AT, f13
|
2215
|
+
| c.olt.d 0, FRET2, f4
|
2216
|
+
| add.d FRET1, FRET2, f4 // (|x| + 2^52) - 2^52
|
2217
|
+
| bc1f 0, >1 // Truncate only if |x| < 2^52.
|
2218
|
+
|. sub.d FRET1, FRET1, f4
|
2219
|
+
| slt AT, AT, r0
|
2220
|
+
|.if "func" == "ceil"
|
2221
|
+
| lui TMP0, 0xbff0 // Hiword of -1 (double). Preserves -0.
|
2222
|
+
|.else
|
2223
|
+
| lui TMP0, 0x3ff0 // Hiword of +1 (double).
|
2224
|
+
|.endif
|
2225
|
+
|.if "func" == "trunc"
|
2226
|
+
| mtc1 TMP0, f5
|
2227
|
+
| c.olt.d 0, FRET2, FRET1 // |x| < result?
|
2228
|
+
| sub.d FRET2, FRET1, f4
|
2229
|
+
| movt.d FRET1, FRET2, 0 // If yes, subtract +1.
|
2230
|
+
| neg.d FRET2, FRET1
|
2231
|
+
| jr ra
|
2232
|
+
|. movn.d FRET1, FRET2, AT // Merge sign bit back in.
|
2233
|
+
|.else
|
2234
|
+
| neg.d FRET2, FRET1
|
2235
|
+
| mtc1 TMP0, f5
|
2236
|
+
| movn.d FRET1, FRET2, AT // Merge sign bit back in.
|
2237
|
+
|.if "func" == "ceil"
|
2238
|
+
| c.olt.d 0, FRET1, FARG1 // x > result?
|
2239
|
+
|.else
|
2240
|
+
| c.olt.d 0, FARG1, FRET1 // x < result?
|
2241
|
+
|.endif
|
2242
|
+
| sub.d FRET2, FRET1, f4 // If yes, subtract +-1.
|
2243
|
+
| jr ra
|
2244
|
+
|. movt.d FRET1, FRET2, 0
|
2245
|
+
|.endif
|
2246
|
+
|1:
|
2247
|
+
| jr ra
|
2248
|
+
|. mov.d FRET1, FARG1
|
2249
|
+
|.endmacro
|
2250
|
+
|
|
2251
|
+
|->vm_floor:
|
2252
|
+
| vm_round floor
|
2253
|
+
|->vm_ceil:
|
2254
|
+
| vm_round ceil
|
2255
|
+
|->vm_trunc:
|
2256
|
+
|.if JIT
|
2257
|
+
| vm_round trunc
|
2258
|
+
|.endif
|
2259
|
+
|
|
2260
|
+
|//-----------------------------------------------------------------------
|
2261
|
+
|//-- Miscellaneous functions --------------------------------------------
|
2262
|
+
|//-----------------------------------------------------------------------
|
2263
|
+
|
|
2264
|
+
|//-----------------------------------------------------------------------
|
2265
|
+
|//-- FFI helper functions -----------------------------------------------
|
2266
|
+
|//-----------------------------------------------------------------------
|
2267
|
+
|
|
2268
|
+
|// Handler for callback functions. Callback slot number in r1, g in r2.
|
2269
|
+
|->vm_ffi_callback:
|
2270
|
+
|.if FFI
|
2271
|
+
|.type CTSTATE, CTState, PC
|
2272
|
+
| saveregs
|
2273
|
+
| lw CTSTATE, GL:r2->ctype_state
|
2274
|
+
| addiu DISPATCH, r2, GG_G2DISP
|
2275
|
+
| load_got lj_ccallback_enter
|
2276
|
+
| sw r1, CTSTATE->cb.slot
|
2277
|
+
| sw CARG1, CTSTATE->cb.gpr[0]
|
2278
|
+
| sw CARG2, CTSTATE->cb.gpr[1]
|
2279
|
+
| sdc1 FARG1, CTSTATE->cb.fpr[0]
|
2280
|
+
| sw CARG3, CTSTATE->cb.gpr[2]
|
2281
|
+
| sw CARG4, CTSTATE->cb.gpr[3]
|
2282
|
+
| sdc1 FARG2, CTSTATE->cb.fpr[1]
|
2283
|
+
| addiu TMP0, sp, CFRAME_SPACE+16
|
2284
|
+
| sw TMP0, CTSTATE->cb.stack
|
2285
|
+
| sw r0, SAVE_PC // Any value outside of bytecode is ok.
|
2286
|
+
| move CARG2, sp
|
2287
|
+
| call_intern lj_ccallback_enter // (CTState *cts, void *cf)
|
2288
|
+
|. move CARG1, CTSTATE
|
2289
|
+
| // Returns lua_State *.
|
2290
|
+
| lw BASE, L:CRET1->base
|
2291
|
+
| lw RC, L:CRET1->top
|
2292
|
+
| move L, CRET1
|
2293
|
+
| lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
|
2294
|
+
| lw LFUNC:RB, FRAME_FUNC(BASE)
|
2295
|
+
| mtc1 TMP3, TOBIT
|
2296
|
+
| li_vmstate INTERP
|
2297
|
+
| li TISNIL, LJ_TNIL
|
2298
|
+
| subu RC, RC, BASE
|
2299
|
+
| st_vmstate
|
2300
|
+
| cvt.d.s TOBIT, TOBIT
|
2301
|
+
| ins_callt
|
2302
|
+
|.endif
|
2303
|
+
|
|
2304
|
+
|->cont_ffi_callback: // Return from FFI callback.
|
2305
|
+
|.if FFI
|
2306
|
+
| load_got lj_ccallback_leave
|
2307
|
+
| lw CTSTATE, DISPATCH_GL(ctype_state)(DISPATCH)
|
2308
|
+
| sw BASE, L->base
|
2309
|
+
| sw RB, L->top
|
2310
|
+
| sw L, CTSTATE->L
|
2311
|
+
| move CARG2, RA
|
2312
|
+
| call_intern lj_ccallback_leave // (CTState *cts, TValue *o)
|
2313
|
+
|. move CARG1, CTSTATE
|
2314
|
+
| lw CRET1, CTSTATE->cb.gpr[0]
|
2315
|
+
| ldc1 FRET1, CTSTATE->cb.fpr[0]
|
2316
|
+
| lw CRET2, CTSTATE->cb.gpr[1]
|
2317
|
+
| b ->vm_leave_unw
|
2318
|
+
|. ldc1 FRET2, CTSTATE->cb.fpr[1]
|
2319
|
+
|.endif
|
2320
|
+
|
|
2321
|
+
|->vm_ffi_call: // Call C function via FFI.
|
2322
|
+
| // Caveat: needs special frame unwinding, see below.
|
2323
|
+
|.if FFI
|
2324
|
+
| .type CCSTATE, CCallState, CARG1
|
2325
|
+
| lw TMP1, CCSTATE->spadj
|
2326
|
+
| lbu CARG2, CCSTATE->nsp
|
2327
|
+
| move TMP2, sp
|
2328
|
+
| subu sp, sp, TMP1
|
2329
|
+
| sw ra, -4(TMP2)
|
2330
|
+
| sll CARG2, CARG2, 2
|
2331
|
+
| sw r16, -8(TMP2)
|
2332
|
+
| sw CCSTATE, -12(TMP2)
|
2333
|
+
| move r16, TMP2
|
2334
|
+
| addiu TMP1, CCSTATE, offsetof(CCallState, stack)
|
2335
|
+
| addiu TMP2, sp, 16
|
2336
|
+
| beqz CARG2, >2
|
2337
|
+
|. addu TMP3, TMP1, CARG2
|
2338
|
+
|1:
|
2339
|
+
| lw TMP0, 0(TMP1)
|
2340
|
+
| addiu TMP1, TMP1, 4
|
2341
|
+
| sltu AT, TMP1, TMP3
|
2342
|
+
| sw TMP0, 0(TMP2)
|
2343
|
+
| bnez AT, <1
|
2344
|
+
|. addiu TMP2, TMP2, 4
|
2345
|
+
|2:
|
2346
|
+
| lw CFUNCADDR, CCSTATE->func
|
2347
|
+
| lw CARG2, CCSTATE->gpr[1]
|
2348
|
+
| lw CARG3, CCSTATE->gpr[2]
|
2349
|
+
| lw CARG4, CCSTATE->gpr[3]
|
2350
|
+
| ldc1 FARG1, CCSTATE->fpr[0]
|
2351
|
+
| ldc1 FARG2, CCSTATE->fpr[1]
|
2352
|
+
| jalr CFUNCADDR
|
2353
|
+
|. lw CARG1, CCSTATE->gpr[0] // Do this last, since CCSTATE is CARG1.
|
2354
|
+
| lw CCSTATE:TMP1, -12(r16)
|
2355
|
+
| lw TMP2, -8(r16)
|
2356
|
+
| lw ra, -4(r16)
|
2357
|
+
| sw CRET1, CCSTATE:TMP1->gpr[0]
|
2358
|
+
| sw CRET2, CCSTATE:TMP1->gpr[1]
|
2359
|
+
| sdc1 FRET1, CCSTATE:TMP1->fpr[0]
|
2360
|
+
| sdc1 FRET2, CCSTATE:TMP1->fpr[1]
|
2361
|
+
| move sp, r16
|
2362
|
+
| jr ra
|
2363
|
+
|. move r16, TMP2
|
2364
|
+
|.endif
|
2365
|
+
|// Note: vm_ffi_call must be the last function in this object file!
|
2366
|
+
|
|
2367
|
+
|//-----------------------------------------------------------------------
|
2368
|
+
}
|
2369
|
+
|
2370
|
+
/* Generate the code for a single instruction. */
|
2371
|
+
static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
2372
|
+
{
|
2373
|
+
int vk = 0;
|
2374
|
+
|=>defop:
|
2375
|
+
|
2376
|
+
switch (op) {
|
2377
|
+
|
2378
|
+
/* -- Comparison ops ---------------------------------------------------- */
|
2379
|
+
|
2380
|
+
/* Remember: all ops branch for a true comparison, fall through otherwise. */
|
2381
|
+
|
2382
|
+
case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
|
2383
|
+
| // RA = src1*8, RD = src2*8, JMP with RD = target
|
2384
|
+
| addu CARG2, BASE, RA
|
2385
|
+
| addu CARG3, BASE, RD
|
2386
|
+
| lw TMP0, HI(CARG2)
|
2387
|
+
| lw TMP1, HI(CARG3)
|
2388
|
+
| ldc1 f0, 0(CARG2)
|
2389
|
+
| ldc1 f2, 0(CARG3)
|
2390
|
+
| sltiu TMP0, TMP0, LJ_TISNUM
|
2391
|
+
| sltiu TMP1, TMP1, LJ_TISNUM
|
2392
|
+
| lhu TMP2, OFS_RD(PC)
|
2393
|
+
| and TMP0, TMP0, TMP1
|
2394
|
+
| addiu PC, PC, 4
|
2395
|
+
| beqz TMP0, ->vmeta_comp
|
2396
|
+
|. lui TMP1, (-(BCBIAS_J*4 >> 16) & 65535)
|
2397
|
+
| decode_RD4b TMP2
|
2398
|
+
| addu TMP2, TMP2, TMP1
|
2399
|
+
if (op == BC_ISLT || op == BC_ISGE) {
|
2400
|
+
| c.olt.d f0, f2
|
2401
|
+
} else {
|
2402
|
+
| c.ole.d f0, f2
|
2403
|
+
}
|
2404
|
+
if (op == BC_ISLT || op == BC_ISLE) {
|
2405
|
+
| movf TMP2, r0
|
2406
|
+
} else {
|
2407
|
+
| movt TMP2, r0
|
2408
|
+
}
|
2409
|
+
| addu PC, PC, TMP2
|
2410
|
+
|1:
|
2411
|
+
| ins_next
|
2412
|
+
break;
|
2413
|
+
|
2414
|
+
case BC_ISEQV: case BC_ISNEV:
|
2415
|
+
vk = op == BC_ISEQV;
|
2416
|
+
| // RA = src1*8, RD = src2*8, JMP with RD = target
|
2417
|
+
| addu RA, BASE, RA
|
2418
|
+
| addiu PC, PC, 4
|
2419
|
+
| lw TMP0, HI(RA)
|
2420
|
+
| ldc1 f0, 0(RA)
|
2421
|
+
| addu RD, BASE, RD
|
2422
|
+
| lhu TMP2, -4+OFS_RD(PC)
|
2423
|
+
| lw TMP1, HI(RD)
|
2424
|
+
| ldc1 f2, 0(RD)
|
2425
|
+
| lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535)
|
2426
|
+
| sltiu AT, TMP0, LJ_TISNUM
|
2427
|
+
| sltiu CARG1, TMP1, LJ_TISNUM
|
2428
|
+
| decode_RD4b TMP2
|
2429
|
+
| and AT, AT, CARG1
|
2430
|
+
| beqz AT, >5
|
2431
|
+
|. addu TMP2, TMP2, TMP3
|
2432
|
+
| c.eq.d f0, f2
|
2433
|
+
if (vk) {
|
2434
|
+
| movf TMP2, r0
|
2435
|
+
} else {
|
2436
|
+
| movt TMP2, r0
|
2437
|
+
}
|
2438
|
+
|1:
|
2439
|
+
| addu PC, PC, TMP2
|
2440
|
+
| ins_next
|
2441
|
+
|5: // Either or both types are not numbers.
|
2442
|
+
| lw CARG2, LO(RA)
|
2443
|
+
| lw CARG3, LO(RD)
|
2444
|
+
|.if FFI
|
2445
|
+
| li TMP3, LJ_TCDATA
|
2446
|
+
| beq TMP0, TMP3, ->vmeta_equal_cd
|
2447
|
+
|.endif
|
2448
|
+
|. sltiu AT, TMP0, LJ_TISPRI // Not a primitive?
|
2449
|
+
|.if FFI
|
2450
|
+
| beq TMP1, TMP3, ->vmeta_equal_cd
|
2451
|
+
|.endif
|
2452
|
+
|. xor TMP3, CARG2, CARG3 // Same tv?
|
2453
|
+
| xor TMP1, TMP1, TMP0 // Same type?
|
2454
|
+
| sltiu CARG1, TMP0, LJ_TISTABUD+1 // Table or userdata?
|
2455
|
+
| movz TMP3, r0, AT // Ignore tv if primitive.
|
2456
|
+
| movn CARG1, r0, TMP1 // Tab/ud and same type?
|
2457
|
+
| or AT, TMP1, TMP3 // Same type && (pri||same tv).
|
2458
|
+
| movz CARG1, r0, AT
|
2459
|
+
| beqz CARG1, <1 // Done if not tab/ud or not same type or same tv.
|
2460
|
+
if (vk) {
|
2461
|
+
|. movn TMP2, r0, AT
|
2462
|
+
} else {
|
2463
|
+
|. movz TMP2, r0, AT
|
2464
|
+
}
|
2465
|
+
| // Different tables or userdatas. Need to check __eq metamethod.
|
2466
|
+
| // Field metatable must be at same offset for GCtab and GCudata!
|
2467
|
+
| lw TAB:TMP1, TAB:CARG2->metatable
|
2468
|
+
| beqz TAB:TMP1, <1 // No metatable?
|
2469
|
+
|. nop
|
2470
|
+
| lbu TMP1, TAB:TMP1->nomm
|
2471
|
+
| andi TMP1, TMP1, 1<<MM_eq
|
2472
|
+
| bnez TMP1, <1 // Or 'no __eq' flag set?
|
2473
|
+
|. nop
|
2474
|
+
| b ->vmeta_equal // Handle __eq metamethod.
|
2475
|
+
|. li CARG4, 1-vk // ne = 0 or 1.
|
2476
|
+
break;
|
2477
|
+
|
2478
|
+
case BC_ISEQS: case BC_ISNES:
|
2479
|
+
vk = op == BC_ISEQS;
|
2480
|
+
| // RA = src*8, RD = str_const*8 (~), JMP with RD = target
|
2481
|
+
| addu RA, BASE, RA
|
2482
|
+
| addiu PC, PC, 4
|
2483
|
+
| lw TMP0, HI(RA)
|
2484
|
+
| srl RD, RD, 1
|
2485
|
+
| lw STR:TMP3, LO(RA)
|
2486
|
+
| subu RD, KBASE, RD
|
2487
|
+
| lhu TMP2, -4+OFS_RD(PC)
|
2488
|
+
|.if FFI
|
2489
|
+
| li AT, LJ_TCDATA
|
2490
|
+
| beq TMP0, AT, ->vmeta_equal_cd
|
2491
|
+
|.endif
|
2492
|
+
|. lw STR:TMP1, -4(RD) // KBASE-4-str_const*4
|
2493
|
+
| addiu TMP0, TMP0, -LJ_TSTR
|
2494
|
+
| decode_RD4b TMP2
|
2495
|
+
| xor TMP1, STR:TMP1, STR:TMP3
|
2496
|
+
| or TMP0, TMP0, TMP1
|
2497
|
+
| lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535)
|
2498
|
+
| addu TMP2, TMP2, TMP3
|
2499
|
+
if (vk) {
|
2500
|
+
| movn TMP2, r0, TMP0
|
2501
|
+
} else {
|
2502
|
+
| movz TMP2, r0, TMP0
|
2503
|
+
}
|
2504
|
+
| addu PC, PC, TMP2
|
2505
|
+
| ins_next
|
2506
|
+
break;
|
2507
|
+
|
2508
|
+
case BC_ISEQN: case BC_ISNEN:
|
2509
|
+
vk = op == BC_ISEQN;
|
2510
|
+
| // RA = src*8, RD = num_const*8, JMP with RD = target
|
2511
|
+
| addu RA, BASE, RA
|
2512
|
+
| addiu PC, PC, 4
|
2513
|
+
| lw TMP0, HI(RA)
|
2514
|
+
| ldc1 f0, 0(RA)
|
2515
|
+
| addu RD, KBASE, RD
|
2516
|
+
| lhu TMP2, -4+OFS_RD(PC)
|
2517
|
+
| ldc1 f2, 0(RD)
|
2518
|
+
| lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535)
|
2519
|
+
| sltiu AT, TMP0, LJ_TISNUM
|
2520
|
+
| decode_RD4b TMP2
|
2521
|
+
|.if FFI
|
2522
|
+
| beqz AT, >5
|
2523
|
+
|.else
|
2524
|
+
| beqz AT, >1
|
2525
|
+
|.endif
|
2526
|
+
|. addu TMP2, TMP2, TMP3
|
2527
|
+
| c.eq.d f0, f2
|
2528
|
+
if (vk) {
|
2529
|
+
| movf TMP2, r0
|
2530
|
+
| addu PC, PC, TMP2
|
2531
|
+
|1:
|
2532
|
+
} else {
|
2533
|
+
| movt TMP2, r0
|
2534
|
+
|1:
|
2535
|
+
| addu PC, PC, TMP2
|
2536
|
+
}
|
2537
|
+
| ins_next
|
2538
|
+
|.if FFI
|
2539
|
+
|5:
|
2540
|
+
| li AT, LJ_TCDATA
|
2541
|
+
| beq TMP0, AT, ->vmeta_equal_cd
|
2542
|
+
|. nop
|
2543
|
+
| b <1
|
2544
|
+
|. nop
|
2545
|
+
|.endif
|
2546
|
+
break;
|
2547
|
+
|
2548
|
+
case BC_ISEQP: case BC_ISNEP:
|
2549
|
+
vk = op == BC_ISEQP;
|
2550
|
+
| // RA = src*8, RD = primitive_type*8 (~), JMP with RD = target
|
2551
|
+
| addu RA, BASE, RA
|
2552
|
+
| srl TMP1, RD, 3
|
2553
|
+
| lw TMP0, HI(RA)
|
2554
|
+
| lhu TMP2, OFS_RD(PC)
|
2555
|
+
| not TMP1, TMP1
|
2556
|
+
| addiu PC, PC, 4
|
2557
|
+
|.if FFI
|
2558
|
+
| li AT, LJ_TCDATA
|
2559
|
+
| beq TMP0, AT, ->vmeta_equal_cd
|
2560
|
+
|.endif
|
2561
|
+
|. xor TMP0, TMP0, TMP1
|
2562
|
+
| decode_RD4b TMP2
|
2563
|
+
| lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535)
|
2564
|
+
| addu TMP2, TMP2, TMP3
|
2565
|
+
if (vk) {
|
2566
|
+
| movn TMP2, r0, TMP0
|
2567
|
+
} else {
|
2568
|
+
| movz TMP2, r0, TMP0
|
2569
|
+
}
|
2570
|
+
| addu PC, PC, TMP2
|
2571
|
+
| ins_next
|
2572
|
+
break;
|
2573
|
+
|
2574
|
+
/* -- Unary test and copy ops ------------------------------------------- */
|
2575
|
+
|
2576
|
+
case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
|
2577
|
+
| // RA = dst*8 or unused, RD = src*8, JMP with RD = target
|
2578
|
+
| addu RD, BASE, RD
|
2579
|
+
| lhu TMP2, OFS_RD(PC)
|
2580
|
+
| lw TMP0, HI(RD)
|
2581
|
+
| addiu PC, PC, 4
|
2582
|
+
if (op == BC_IST || op == BC_ISF) {
|
2583
|
+
| sltiu TMP0, TMP0, LJ_TISTRUECOND
|
2584
|
+
| decode_RD4b TMP2
|
2585
|
+
| lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535)
|
2586
|
+
| addu TMP2, TMP2, TMP3
|
2587
|
+
if (op == BC_IST) {
|
2588
|
+
| movz TMP2, r0, TMP0
|
2589
|
+
} else {
|
2590
|
+
| movn TMP2, r0, TMP0
|
2591
|
+
}
|
2592
|
+
| addu PC, PC, TMP2
|
2593
|
+
} else {
|
2594
|
+
| sltiu TMP0, TMP0, LJ_TISTRUECOND
|
2595
|
+
| ldc1 f0, 0(RD)
|
2596
|
+
if (op == BC_ISTC) {
|
2597
|
+
| beqz TMP0, >1
|
2598
|
+
} else {
|
2599
|
+
| bnez TMP0, >1
|
2600
|
+
}
|
2601
|
+
|. addu RA, BASE, RA
|
2602
|
+
| decode_RD4b TMP2
|
2603
|
+
| lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535)
|
2604
|
+
| addu TMP2, TMP2, TMP3
|
2605
|
+
| sdc1 f0, 0(RA)
|
2606
|
+
| addu PC, PC, TMP2
|
2607
|
+
|1:
|
2608
|
+
}
|
2609
|
+
| ins_next
|
2610
|
+
break;
|
2611
|
+
|
2612
|
+
case BC_ISTYPE:
|
2613
|
+
| // RA = src*8, RD = -type*8
|
2614
|
+
| addu TMP2, BASE, RA
|
2615
|
+
| srl TMP1, RD, 3
|
2616
|
+
| lw TMP0, HI(TMP2)
|
2617
|
+
| ins_next1
|
2618
|
+
| addu AT, TMP0, TMP1
|
2619
|
+
| bnez AT, ->vmeta_istype
|
2620
|
+
|. ins_next2
|
2621
|
+
break;
|
2622
|
+
case BC_ISNUM:
|
2623
|
+
| // RA = src*8, RD = -(TISNUM-1)*8
|
2624
|
+
| addu TMP2, BASE, RA
|
2625
|
+
| lw TMP0, HI(TMP2)
|
2626
|
+
| ins_next1
|
2627
|
+
| sltiu AT, TMP0, LJ_TISNUM
|
2628
|
+
| beqz AT, ->vmeta_istype
|
2629
|
+
|. ins_next2
|
2630
|
+
break;
|
2631
|
+
|
2632
|
+
/* -- Unary ops --------------------------------------------------------- */
|
2633
|
+
|
2634
|
+
case BC_MOV:
|
2635
|
+
| // RA = dst*8, RD = src*8
|
2636
|
+
| addu RD, BASE, RD
|
2637
|
+
| addu RA, BASE, RA
|
2638
|
+
| ldc1 f0, 0(RD)
|
2639
|
+
| ins_next1
|
2640
|
+
| sdc1 f0, 0(RA)
|
2641
|
+
| ins_next2
|
2642
|
+
break;
|
2643
|
+
case BC_NOT:
|
2644
|
+
| // RA = dst*8, RD = src*8
|
2645
|
+
| addu RD, BASE, RD
|
2646
|
+
| addu RA, BASE, RA
|
2647
|
+
| lw TMP0, HI(RD)
|
2648
|
+
| li TMP1, LJ_TFALSE
|
2649
|
+
| sltiu TMP0, TMP0, LJ_TISTRUECOND
|
2650
|
+
| addiu TMP1, TMP0, LJ_TTRUE
|
2651
|
+
| ins_next1
|
2652
|
+
| sw TMP1, HI(RA)
|
2653
|
+
| ins_next2
|
2654
|
+
break;
|
2655
|
+
case BC_UNM:
|
2656
|
+
| // RA = dst*8, RD = src*8
|
2657
|
+
| addu CARG3, BASE, RD
|
2658
|
+
| addu RA, BASE, RA
|
2659
|
+
| lw TMP0, HI(CARG3)
|
2660
|
+
| ldc1 f0, 0(CARG3)
|
2661
|
+
| sltiu AT, TMP0, LJ_TISNUM
|
2662
|
+
| beqz AT, ->vmeta_unm
|
2663
|
+
|. neg.d f0, f0
|
2664
|
+
| ins_next1
|
2665
|
+
| sdc1 f0, 0(RA)
|
2666
|
+
| ins_next2
|
2667
|
+
break;
|
2668
|
+
case BC_LEN:
|
2669
|
+
| // RA = dst*8, RD = src*8
|
2670
|
+
| addu CARG2, BASE, RD
|
2671
|
+
| addu RA, BASE, RA
|
2672
|
+
| lw TMP0, HI(CARG2)
|
2673
|
+
| lw CARG1, LO(CARG2)
|
2674
|
+
| li AT, LJ_TSTR
|
2675
|
+
| bne TMP0, AT, >2
|
2676
|
+
|. li AT, LJ_TTAB
|
2677
|
+
| lw CRET1, STR:CARG1->len
|
2678
|
+
|1:
|
2679
|
+
| mtc1 CRET1, f0
|
2680
|
+
| cvt.d.w f0, f0
|
2681
|
+
| ins_next1
|
2682
|
+
| sdc1 f0, 0(RA)
|
2683
|
+
| ins_next2
|
2684
|
+
|2:
|
2685
|
+
| bne TMP0, AT, ->vmeta_len
|
2686
|
+
|. nop
|
2687
|
+
#if LJ_52
|
2688
|
+
| lw TAB:TMP2, TAB:CARG1->metatable
|
2689
|
+
| bnez TAB:TMP2, >9
|
2690
|
+
|. nop
|
2691
|
+
|3:
|
2692
|
+
#endif
|
2693
|
+
|->BC_LEN_Z:
|
2694
|
+
| load_got lj_tab_len
|
2695
|
+
| call_intern lj_tab_len // (GCtab *t)
|
2696
|
+
|. nop
|
2697
|
+
| // Returns uint32_t (but less than 2^31).
|
2698
|
+
| b <1
|
2699
|
+
|. nop
|
2700
|
+
#if LJ_52
|
2701
|
+
|9:
|
2702
|
+
| lbu TMP0, TAB:TMP2->nomm
|
2703
|
+
| andi TMP0, TMP0, 1<<MM_len
|
2704
|
+
| bnez TMP0, <3 // 'no __len' flag set: done.
|
2705
|
+
|. nop
|
2706
|
+
| b ->vmeta_len
|
2707
|
+
|. nop
|
2708
|
+
#endif
|
2709
|
+
break;
|
2710
|
+
|
2711
|
+
/* -- Binary ops -------------------------------------------------------- */
|
2712
|
+
|
2713
|
+
|.macro ins_arithpre
|
2714
|
+
||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
|
2715
|
+
| decode_RB8a RB, INS
|
2716
|
+
| decode_RB8b RB
|
2717
|
+
| decode_RDtoRC8 RC, RD
|
2718
|
+
| // RA = dst*8, RB = src1*8, RC = src2*8 | num_const*8
|
2719
|
+
||switch (vk) {
|
2720
|
+
||case 0:
|
2721
|
+
| addu CARG3, BASE, RB
|
2722
|
+
| addu CARG4, KBASE, RC
|
2723
|
+
| lw TMP1, HI(CARG3)
|
2724
|
+
| ldc1 f20, 0(CARG3)
|
2725
|
+
| ldc1 f22, 0(CARG4)
|
2726
|
+
| sltiu AT, TMP1, LJ_TISNUM
|
2727
|
+
|| break;
|
2728
|
+
||case 1:
|
2729
|
+
| addu CARG4, BASE, RB
|
2730
|
+
| addu CARG3, KBASE, RC
|
2731
|
+
| lw TMP1, HI(CARG4)
|
2732
|
+
| ldc1 f22, 0(CARG4)
|
2733
|
+
| ldc1 f20, 0(CARG3)
|
2734
|
+
| sltiu AT, TMP1, LJ_TISNUM
|
2735
|
+
|| break;
|
2736
|
+
||default:
|
2737
|
+
| addu CARG3, BASE, RB
|
2738
|
+
| addu CARG4, BASE, RC
|
2739
|
+
| lw TMP1, HI(CARG3)
|
2740
|
+
| lw TMP2, HI(CARG4)
|
2741
|
+
| ldc1 f20, 0(CARG3)
|
2742
|
+
| ldc1 f22, 0(CARG4)
|
2743
|
+
| sltiu AT, TMP1, LJ_TISNUM
|
2744
|
+
| sltiu TMP0, TMP2, LJ_TISNUM
|
2745
|
+
| and AT, AT, TMP0
|
2746
|
+
|| break;
|
2747
|
+
||}
|
2748
|
+
| beqz AT, ->vmeta_arith
|
2749
|
+
|. addu RA, BASE, RA
|
2750
|
+
|.endmacro
|
2751
|
+
|
|
2752
|
+
|.macro fpmod, a, b, c
|
2753
|
+
|->BC_MODVN_Z:
|
2754
|
+
| bal ->vm_floor // floor(b/c)
|
2755
|
+
|. div.d FARG1, b, c
|
2756
|
+
| mul.d a, FRET1, c
|
2757
|
+
| sub.d a, b, a // b - floor(b/c)*c
|
2758
|
+
|.endmacro
|
2759
|
+
|
|
2760
|
+
|.macro ins_arith, ins
|
2761
|
+
| ins_arithpre
|
2762
|
+
|.if "ins" == "fpmod_"
|
2763
|
+
| b ->BC_MODVN_Z // Avoid 3 copies. It's slow anyway.
|
2764
|
+
|. nop
|
2765
|
+
|.else
|
2766
|
+
| ins f0, f20, f22
|
2767
|
+
| ins_next1
|
2768
|
+
| sdc1 f0, 0(RA)
|
2769
|
+
| ins_next2
|
2770
|
+
|.endif
|
2771
|
+
|.endmacro
|
2772
|
+
|
2773
|
+
case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
|
2774
|
+
| ins_arith add.d
|
2775
|
+
break;
|
2776
|
+
case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
|
2777
|
+
| ins_arith sub.d
|
2778
|
+
break;
|
2779
|
+
case BC_MULVN: case BC_MULNV: case BC_MULVV:
|
2780
|
+
| ins_arith mul.d
|
2781
|
+
break;
|
2782
|
+
case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
|
2783
|
+
| ins_arith div.d
|
2784
|
+
break;
|
2785
|
+
case BC_MODVN:
|
2786
|
+
| ins_arith fpmod
|
2787
|
+
break;
|
2788
|
+
case BC_MODNV: case BC_MODVV:
|
2789
|
+
| ins_arith fpmod_
|
2790
|
+
break;
|
2791
|
+
case BC_POW:
|
2792
|
+
| decode_RB8a RB, INS
|
2793
|
+
| decode_RB8b RB
|
2794
|
+
| decode_RDtoRC8 RC, RD
|
2795
|
+
| addu CARG3, BASE, RB
|
2796
|
+
| addu CARG4, BASE, RC
|
2797
|
+
| lw TMP1, HI(CARG3)
|
2798
|
+
| lw TMP2, HI(CARG4)
|
2799
|
+
| ldc1 FARG1, 0(CARG3)
|
2800
|
+
| ldc1 FARG2, 0(CARG4)
|
2801
|
+
| sltiu AT, TMP1, LJ_TISNUM
|
2802
|
+
| sltiu TMP0, TMP2, LJ_TISNUM
|
2803
|
+
| and AT, AT, TMP0
|
2804
|
+
| load_got pow
|
2805
|
+
| beqz AT, ->vmeta_arith
|
2806
|
+
|. addu RA, BASE, RA
|
2807
|
+
| call_extern
|
2808
|
+
|. nop
|
2809
|
+
| ins_next1
|
2810
|
+
| sdc1 FRET1, 0(RA)
|
2811
|
+
| ins_next2
|
2812
|
+
break;
|
2813
|
+
|
2814
|
+
case BC_CAT:
|
2815
|
+
| // RA = dst*8, RB = src_start*8, RC = src_end*8
|
2816
|
+
| decode_RB8a RB, INS
|
2817
|
+
| decode_RB8b RB
|
2818
|
+
| decode_RDtoRC8 RC, RD
|
2819
|
+
| subu CARG3, RC, RB
|
2820
|
+
| sw BASE, L->base
|
2821
|
+
| addu CARG2, BASE, RC
|
2822
|
+
| move MULTRES, RB
|
2823
|
+
|->BC_CAT_Z:
|
2824
|
+
| load_got lj_meta_cat
|
2825
|
+
| srl CARG3, CARG3, 3
|
2826
|
+
| sw PC, SAVE_PC
|
2827
|
+
| call_intern lj_meta_cat // (lua_State *L, TValue *top, int left)
|
2828
|
+
|. move CARG1, L
|
2829
|
+
| // Returns NULL (finished) or TValue * (metamethod).
|
2830
|
+
| bnez CRET1, ->vmeta_binop
|
2831
|
+
|. lw BASE, L->base
|
2832
|
+
| addu RB, BASE, MULTRES
|
2833
|
+
| ldc1 f0, 0(RB)
|
2834
|
+
| addu RA, BASE, RA
|
2835
|
+
| ins_next1
|
2836
|
+
| sdc1 f0, 0(RA) // Copy result from RB to RA.
|
2837
|
+
| ins_next2
|
2838
|
+
break;
|
2839
|
+
|
2840
|
+
/* -- Constant ops ------------------------------------------------------ */
|
2841
|
+
|
2842
|
+
case BC_KSTR:
|
2843
|
+
| // RA = dst*8, RD = str_const*8 (~)
|
2844
|
+
| srl TMP1, RD, 1
|
2845
|
+
| subu TMP1, KBASE, TMP1
|
2846
|
+
| ins_next1
|
2847
|
+
| lw TMP0, -4(TMP1) // KBASE-4-str_const*4
|
2848
|
+
| addu RA, BASE, RA
|
2849
|
+
| li TMP2, LJ_TSTR
|
2850
|
+
| sw TMP0, LO(RA)
|
2851
|
+
| sw TMP2, HI(RA)
|
2852
|
+
| ins_next2
|
2853
|
+
break;
|
2854
|
+
case BC_KCDATA:
|
2855
|
+
|.if FFI
|
2856
|
+
| // RA = dst*8, RD = cdata_const*8 (~)
|
2857
|
+
| srl TMP1, RD, 1
|
2858
|
+
| subu TMP1, KBASE, TMP1
|
2859
|
+
| ins_next1
|
2860
|
+
| lw TMP0, -4(TMP1) // KBASE-4-cdata_const*4
|
2861
|
+
| addu RA, BASE, RA
|
2862
|
+
| li TMP2, LJ_TCDATA
|
2863
|
+
| sw TMP0, LO(RA)
|
2864
|
+
| sw TMP2, HI(RA)
|
2865
|
+
| ins_next2
|
2866
|
+
|.endif
|
2867
|
+
break;
|
2868
|
+
case BC_KSHORT:
|
2869
|
+
| // RA = dst*8, RD = int16_literal*8
|
2870
|
+
| sra RD, INS, 16
|
2871
|
+
| mtc1 RD, f0
|
2872
|
+
| addu RA, BASE, RA
|
2873
|
+
| cvt.d.w f0, f0
|
2874
|
+
| ins_next1
|
2875
|
+
| sdc1 f0, 0(RA)
|
2876
|
+
| ins_next2
|
2877
|
+
break;
|
2878
|
+
case BC_KNUM:
|
2879
|
+
| // RA = dst*8, RD = num_const*8
|
2880
|
+
| addu RD, KBASE, RD
|
2881
|
+
| addu RA, BASE, RA
|
2882
|
+
| ldc1 f0, 0(RD)
|
2883
|
+
| ins_next1
|
2884
|
+
| sdc1 f0, 0(RA)
|
2885
|
+
| ins_next2
|
2886
|
+
break;
|
2887
|
+
case BC_KPRI:
|
2888
|
+
| // RA = dst*8, RD = primitive_type*8 (~)
|
2889
|
+
| srl TMP1, RD, 3
|
2890
|
+
| addu RA, BASE, RA
|
2891
|
+
| not TMP0, TMP1
|
2892
|
+
| ins_next1
|
2893
|
+
| sw TMP0, HI(RA)
|
2894
|
+
| ins_next2
|
2895
|
+
break;
|
2896
|
+
case BC_KNIL:
|
2897
|
+
| // RA = base*8, RD = end*8
|
2898
|
+
| addu RA, BASE, RA
|
2899
|
+
| sw TISNIL, HI(RA)
|
2900
|
+
| addiu RA, RA, 8
|
2901
|
+
| addu RD, BASE, RD
|
2902
|
+
|1:
|
2903
|
+
| sw TISNIL, HI(RA)
|
2904
|
+
| slt AT, RA, RD
|
2905
|
+
| bnez AT, <1
|
2906
|
+
|. addiu RA, RA, 8
|
2907
|
+
| ins_next_
|
2908
|
+
break;
|
2909
|
+
|
2910
|
+
/* -- Upvalue and function ops ------------------------------------------ */
|
2911
|
+
|
2912
|
+
case BC_UGET:
|
2913
|
+
| // RA = dst*8, RD = uvnum*8
|
2914
|
+
| lw LFUNC:RB, FRAME_FUNC(BASE)
|
2915
|
+
| srl RD, RD, 1
|
2916
|
+
| addu RD, RD, LFUNC:RB
|
2917
|
+
| lw UPVAL:RB, LFUNC:RD->uvptr
|
2918
|
+
| ins_next1
|
2919
|
+
| lw TMP1, UPVAL:RB->v
|
2920
|
+
| ldc1 f0, 0(TMP1)
|
2921
|
+
| addu RA, BASE, RA
|
2922
|
+
| sdc1 f0, 0(RA)
|
2923
|
+
| ins_next2
|
2924
|
+
break;
|
2925
|
+
case BC_USETV:
|
2926
|
+
| // RA = uvnum*8, RD = src*8
|
2927
|
+
| lw LFUNC:RB, FRAME_FUNC(BASE)
|
2928
|
+
| srl RA, RA, 1
|
2929
|
+
| addu RD, BASE, RD
|
2930
|
+
| addu RA, RA, LFUNC:RB
|
2931
|
+
| ldc1 f0, 0(RD)
|
2932
|
+
| lw UPVAL:RB, LFUNC:RA->uvptr
|
2933
|
+
| lbu TMP3, UPVAL:RB->marked
|
2934
|
+
| lw CARG2, UPVAL:RB->v
|
2935
|
+
| andi TMP3, TMP3, LJ_GC_BLACK // isblack(uv)
|
2936
|
+
| lbu TMP0, UPVAL:RB->closed
|
2937
|
+
| lw TMP2, HI(RD)
|
2938
|
+
| sdc1 f0, 0(CARG2)
|
2939
|
+
| li AT, LJ_GC_BLACK|1
|
2940
|
+
| or TMP3, TMP3, TMP0
|
2941
|
+
| beq TMP3, AT, >2 // Upvalue is closed and black?
|
2942
|
+
|. addiu TMP2, TMP2, -(LJ_TNUMX+1)
|
2943
|
+
|1:
|
2944
|
+
| ins_next
|
2945
|
+
|
|
2946
|
+
|2: // Check if new value is collectable.
|
2947
|
+
| sltiu AT, TMP2, LJ_TISGCV - (LJ_TNUMX+1)
|
2948
|
+
| beqz AT, <1 // tvisgcv(v)
|
2949
|
+
|. lw TMP1, LO(RD)
|
2950
|
+
| lbu TMP3, GCOBJ:TMP1->gch.marked
|
2951
|
+
| andi TMP3, TMP3, LJ_GC_WHITES // iswhite(v)
|
2952
|
+
| beqz TMP3, <1
|
2953
|
+
|. load_got lj_gc_barrieruv
|
2954
|
+
| // Crossed a write barrier. Move the barrier forward.
|
2955
|
+
| call_intern lj_gc_barrieruv // (global_State *g, TValue *tv)
|
2956
|
+
|. addiu CARG1, DISPATCH, GG_DISP2G
|
2957
|
+
| b <1
|
2958
|
+
|. nop
|
2959
|
+
break;
|
2960
|
+
case BC_USETS:
|
2961
|
+
| // RA = uvnum*8, RD = str_const*8 (~)
|
2962
|
+
| lw LFUNC:RB, FRAME_FUNC(BASE)
|
2963
|
+
| srl RA, RA, 1
|
2964
|
+
| srl TMP1, RD, 1
|
2965
|
+
| addu RA, RA, LFUNC:RB
|
2966
|
+
| subu TMP1, KBASE, TMP1
|
2967
|
+
| lw UPVAL:RB, LFUNC:RA->uvptr
|
2968
|
+
| lw STR:TMP1, -4(TMP1) // KBASE-4-str_const*4
|
2969
|
+
| lbu TMP2, UPVAL:RB->marked
|
2970
|
+
| lw CARG2, UPVAL:RB->v
|
2971
|
+
| lbu TMP3, STR:TMP1->marked
|
2972
|
+
| andi AT, TMP2, LJ_GC_BLACK // isblack(uv)
|
2973
|
+
| lbu TMP2, UPVAL:RB->closed
|
2974
|
+
| li TMP0, LJ_TSTR
|
2975
|
+
| sw STR:TMP1, LO(CARG2)
|
2976
|
+
| bnez AT, >2
|
2977
|
+
|. sw TMP0, HI(CARG2)
|
2978
|
+
|1:
|
2979
|
+
| ins_next
|
2980
|
+
|
|
2981
|
+
|2: // Check if string is white and ensure upvalue is closed.
|
2982
|
+
| beqz TMP2, <1
|
2983
|
+
|. andi AT, TMP3, LJ_GC_WHITES // iswhite(str)
|
2984
|
+
| beqz AT, <1
|
2985
|
+
|. load_got lj_gc_barrieruv
|
2986
|
+
| // Crossed a write barrier. Move the barrier forward.
|
2987
|
+
| call_intern lj_gc_barrieruv // (global_State *g, TValue *tv)
|
2988
|
+
|. addiu CARG1, DISPATCH, GG_DISP2G
|
2989
|
+
| b <1
|
2990
|
+
|. nop
|
2991
|
+
break;
|
2992
|
+
case BC_USETN:
|
2993
|
+
| // RA = uvnum*8, RD = num_const*8
|
2994
|
+
| lw LFUNC:RB, FRAME_FUNC(BASE)
|
2995
|
+
| srl RA, RA, 1
|
2996
|
+
| addu RD, KBASE, RD
|
2997
|
+
| addu RA, RA, LFUNC:RB
|
2998
|
+
| ldc1 f0, 0(RD)
|
2999
|
+
| lw UPVAL:RB, LFUNC:RA->uvptr
|
3000
|
+
| ins_next1
|
3001
|
+
| lw TMP1, UPVAL:RB->v
|
3002
|
+
| sdc1 f0, 0(TMP1)
|
3003
|
+
| ins_next2
|
3004
|
+
break;
|
3005
|
+
case BC_USETP:
|
3006
|
+
| // RA = uvnum*8, RD = primitive_type*8 (~)
|
3007
|
+
| lw LFUNC:RB, FRAME_FUNC(BASE)
|
3008
|
+
| srl RA, RA, 1
|
3009
|
+
| srl TMP0, RD, 3
|
3010
|
+
| addu RA, RA, LFUNC:RB
|
3011
|
+
| not TMP0, TMP0
|
3012
|
+
| lw UPVAL:RB, LFUNC:RA->uvptr
|
3013
|
+
| ins_next1
|
3014
|
+
| lw TMP1, UPVAL:RB->v
|
3015
|
+
| sw TMP0, HI(TMP1)
|
3016
|
+
| ins_next2
|
3017
|
+
break;
|
3018
|
+
|
3019
|
+
case BC_UCLO:
|
3020
|
+
| // RA = level*8, RD = target
|
3021
|
+
| lw TMP2, L->openupval
|
3022
|
+
| branch_RD // Do this first since RD is not saved.
|
3023
|
+
| load_got lj_func_closeuv
|
3024
|
+
| sw BASE, L->base
|
3025
|
+
| beqz TMP2, >1
|
3026
|
+
|. move CARG1, L
|
3027
|
+
| call_intern lj_func_closeuv // (lua_State *L, TValue *level)
|
3028
|
+
|. addu CARG2, BASE, RA
|
3029
|
+
| lw BASE, L->base
|
3030
|
+
|1:
|
3031
|
+
| ins_next
|
3032
|
+
break;
|
3033
|
+
|
3034
|
+
case BC_FNEW:
|
3035
|
+
| // RA = dst*8, RD = proto_const*8 (~) (holding function prototype)
|
3036
|
+
| srl TMP1, RD, 1
|
3037
|
+
| load_got lj_func_newL_gc
|
3038
|
+
| subu TMP1, KBASE, TMP1
|
3039
|
+
| lw CARG3, FRAME_FUNC(BASE)
|
3040
|
+
| lw CARG2, -4(TMP1) // KBASE-4-tab_const*4
|
3041
|
+
| sw BASE, L->base
|
3042
|
+
| sw PC, SAVE_PC
|
3043
|
+
| // (lua_State *L, GCproto *pt, GCfuncL *parent)
|
3044
|
+
| call_intern lj_func_newL_gc
|
3045
|
+
|. move CARG1, L
|
3046
|
+
| // Returns GCfuncL *.
|
3047
|
+
| lw BASE, L->base
|
3048
|
+
| li TMP0, LJ_TFUNC
|
3049
|
+
| ins_next1
|
3050
|
+
| addu RA, BASE, RA
|
3051
|
+
| sw TMP0, HI(RA)
|
3052
|
+
| sw LFUNC:CRET1, LO(RA)
|
3053
|
+
| ins_next2
|
3054
|
+
break;
|
3055
|
+
|
3056
|
+
/* -- Table ops --------------------------------------------------------- */
|
3057
|
+
|
3058
|
+
case BC_TNEW:
|
3059
|
+
case BC_TDUP:
|
3060
|
+
| // RA = dst*8, RD = (hbits|asize)*8 | tab_const*8 (~)
|
3061
|
+
| lw TMP0, DISPATCH_GL(gc.total)(DISPATCH)
|
3062
|
+
| lw TMP1, DISPATCH_GL(gc.threshold)(DISPATCH)
|
3063
|
+
| sw BASE, L->base
|
3064
|
+
| sw PC, SAVE_PC
|
3065
|
+
| sltu AT, TMP0, TMP1
|
3066
|
+
| beqz AT, >5
|
3067
|
+
|1:
|
3068
|
+
if (op == BC_TNEW) {
|
3069
|
+
| load_got lj_tab_new
|
3070
|
+
| srl CARG2, RD, 3
|
3071
|
+
| andi CARG2, CARG2, 0x7ff
|
3072
|
+
| li TMP0, 0x801
|
3073
|
+
| addiu AT, CARG2, -0x7ff
|
3074
|
+
| srl CARG3, RD, 14
|
3075
|
+
| movz CARG2, TMP0, AT
|
3076
|
+
| // (lua_State *L, int32_t asize, uint32_t hbits)
|
3077
|
+
| call_intern lj_tab_new
|
3078
|
+
|. move CARG1, L
|
3079
|
+
| // Returns Table *.
|
3080
|
+
} else {
|
3081
|
+
| load_got lj_tab_dup
|
3082
|
+
| srl TMP1, RD, 1
|
3083
|
+
| subu TMP1, KBASE, TMP1
|
3084
|
+
| move CARG1, L
|
3085
|
+
| call_intern lj_tab_dup // (lua_State *L, Table *kt)
|
3086
|
+
|. lw CARG2, -4(TMP1) // KBASE-4-str_const*4
|
3087
|
+
| // Returns Table *.
|
3088
|
+
}
|
3089
|
+
| lw BASE, L->base
|
3090
|
+
| ins_next1
|
3091
|
+
| addu RA, BASE, RA
|
3092
|
+
| li TMP0, LJ_TTAB
|
3093
|
+
| sw TAB:CRET1, LO(RA)
|
3094
|
+
| sw TMP0, HI(RA)
|
3095
|
+
| ins_next2
|
3096
|
+
|5:
|
3097
|
+
| load_got lj_gc_step_fixtop
|
3098
|
+
| move MULTRES, RD
|
3099
|
+
| call_intern lj_gc_step_fixtop // (lua_State *L)
|
3100
|
+
|. move CARG1, L
|
3101
|
+
| b <1
|
3102
|
+
|. move RD, MULTRES
|
3103
|
+
break;
|
3104
|
+
|
3105
|
+
case BC_GGET:
|
3106
|
+
| // RA = dst*8, RD = str_const*8 (~)
|
3107
|
+
case BC_GSET:
|
3108
|
+
| // RA = src*8, RD = str_const*8 (~)
|
3109
|
+
| lw LFUNC:TMP2, FRAME_FUNC(BASE)
|
3110
|
+
| srl TMP1, RD, 1
|
3111
|
+
| subu TMP1, KBASE, TMP1
|
3112
|
+
| lw TAB:RB, LFUNC:TMP2->env
|
3113
|
+
| lw STR:RC, -4(TMP1) // KBASE-4-str_const*4
|
3114
|
+
if (op == BC_GGET) {
|
3115
|
+
| b ->BC_TGETS_Z
|
3116
|
+
} else {
|
3117
|
+
| b ->BC_TSETS_Z
|
3118
|
+
}
|
3119
|
+
|. addu RA, BASE, RA
|
3120
|
+
break;
|
3121
|
+
|
3122
|
+
case BC_TGETV:
|
3123
|
+
| // RA = dst*8, RB = table*8, RC = key*8
|
3124
|
+
| decode_RB8a RB, INS
|
3125
|
+
| decode_RB8b RB
|
3126
|
+
| decode_RDtoRC8 RC, RD
|
3127
|
+
| addu CARG2, BASE, RB
|
3128
|
+
| addu CARG3, BASE, RC
|
3129
|
+
| lw TMP1, HI(CARG2)
|
3130
|
+
| lw TMP2, HI(CARG3)
|
3131
|
+
| lw TAB:RB, LO(CARG2)
|
3132
|
+
| li AT, LJ_TTAB
|
3133
|
+
| ldc1 f0, 0(CARG3)
|
3134
|
+
| bne TMP1, AT, ->vmeta_tgetv
|
3135
|
+
|. addu RA, BASE, RA
|
3136
|
+
| sltiu AT, TMP2, LJ_TISNUM
|
3137
|
+
| beqz AT, >5
|
3138
|
+
|. li AT, LJ_TSTR
|
3139
|
+
|
|
3140
|
+
| // Convert number key to integer, check for integerness and range.
|
3141
|
+
| cvt.w.d f2, f0
|
3142
|
+
| lw TMP0, TAB:RB->asize
|
3143
|
+
| mfc1 TMP2, f2
|
3144
|
+
| cvt.d.w f4, f2
|
3145
|
+
| lw TMP1, TAB:RB->array
|
3146
|
+
| c.eq.d f0, f4
|
3147
|
+
| sltu AT, TMP2, TMP0
|
3148
|
+
| movf AT, r0
|
3149
|
+
| sll TMP2, TMP2, 3
|
3150
|
+
| beqz AT, ->vmeta_tgetv // Integer key and in array part?
|
3151
|
+
|. addu TMP2, TMP1, TMP2
|
3152
|
+
| lw TMP0, HI(TMP2)
|
3153
|
+
| beq TMP0, TISNIL, >2
|
3154
|
+
|. ldc1 f0, 0(TMP2)
|
3155
|
+
|1:
|
3156
|
+
| ins_next1
|
3157
|
+
| sdc1 f0, 0(RA)
|
3158
|
+
| ins_next2
|
3159
|
+
|
|
3160
|
+
|2: // Check for __index if table value is nil.
|
3161
|
+
| lw TAB:TMP2, TAB:RB->metatable
|
3162
|
+
| beqz TAB:TMP2, <1 // No metatable: done.
|
3163
|
+
|. nop
|
3164
|
+
| lbu TMP0, TAB:TMP2->nomm
|
3165
|
+
| andi TMP0, TMP0, 1<<MM_index
|
3166
|
+
| bnez TMP0, <1 // 'no __index' flag set: done.
|
3167
|
+
|. nop
|
3168
|
+
| b ->vmeta_tgetv
|
3169
|
+
|. nop
|
3170
|
+
|
|
3171
|
+
|5:
|
3172
|
+
| bne TMP2, AT, ->vmeta_tgetv
|
3173
|
+
|. lw STR:RC, LO(CARG3)
|
3174
|
+
| b ->BC_TGETS_Z // String key?
|
3175
|
+
|. nop
|
3176
|
+
break;
|
3177
|
+
case BC_TGETS:
|
3178
|
+
| // RA = dst*8, RB = table*8, RC = str_const*4 (~)
|
3179
|
+
| decode_RB8a RB, INS
|
3180
|
+
| decode_RB8b RB
|
3181
|
+
| addu CARG2, BASE, RB
|
3182
|
+
| decode_RC4a RC, INS
|
3183
|
+
| lw TMP0, HI(CARG2)
|
3184
|
+
| decode_RC4b RC
|
3185
|
+
| li AT, LJ_TTAB
|
3186
|
+
| lw TAB:RB, LO(CARG2)
|
3187
|
+
| subu CARG3, KBASE, RC
|
3188
|
+
| lw STR:RC, -4(CARG3) // KBASE-4-str_const*4
|
3189
|
+
| bne TMP0, AT, ->vmeta_tgets1
|
3190
|
+
|. addu RA, BASE, RA
|
3191
|
+
|->BC_TGETS_Z:
|
3192
|
+
| // TAB:RB = GCtab *, STR:RC = GCstr *, RA = dst*8
|
3193
|
+
| lw TMP0, TAB:RB->hmask
|
3194
|
+
| lw TMP1, STR:RC->hash
|
3195
|
+
| lw NODE:TMP2, TAB:RB->node
|
3196
|
+
| and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask
|
3197
|
+
| sll TMP0, TMP1, 5
|
3198
|
+
| sll TMP1, TMP1, 3
|
3199
|
+
| subu TMP1, TMP0, TMP1
|
3200
|
+
| addu NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8)
|
3201
|
+
|1:
|
3202
|
+
| lw CARG1, offsetof(Node, key)+HI(NODE:TMP2)
|
3203
|
+
| lw TMP0, offsetof(Node, key)+LO(NODE:TMP2)
|
3204
|
+
| lw NODE:TMP1, NODE:TMP2->next
|
3205
|
+
| lw CARG2, offsetof(Node, val)+HI(NODE:TMP2)
|
3206
|
+
| addiu CARG1, CARG1, -LJ_TSTR
|
3207
|
+
| xor TMP0, TMP0, STR:RC
|
3208
|
+
| or AT, CARG1, TMP0
|
3209
|
+
| bnez AT, >4
|
3210
|
+
|. lw TAB:TMP3, TAB:RB->metatable
|
3211
|
+
| beq CARG2, TISNIL, >5 // Key found, but nil value?
|
3212
|
+
|. lw CARG1, offsetof(Node, val)+LO(NODE:TMP2)
|
3213
|
+
|3:
|
3214
|
+
| ins_next1
|
3215
|
+
| sw CARG2, HI(RA)
|
3216
|
+
| sw CARG1, LO(RA)
|
3217
|
+
| ins_next2
|
3218
|
+
|
|
3219
|
+
|4: // Follow hash chain.
|
3220
|
+
| bnez NODE:TMP1, <1
|
3221
|
+
|. move NODE:TMP2, NODE:TMP1
|
3222
|
+
| // End of hash chain: key not found, nil result.
|
3223
|
+
|
|
3224
|
+
|5: // Check for __index if table value is nil.
|
3225
|
+
| beqz TAB:TMP3, <3 // No metatable: done.
|
3226
|
+
|. li CARG2, LJ_TNIL
|
3227
|
+
| lbu TMP0, TAB:TMP3->nomm
|
3228
|
+
| andi TMP0, TMP0, 1<<MM_index
|
3229
|
+
| bnez TMP0, <3 // 'no __index' flag set: done.
|
3230
|
+
|. nop
|
3231
|
+
| b ->vmeta_tgets
|
3232
|
+
|. nop
|
3233
|
+
break;
|
3234
|
+
case BC_TGETB:
|
3235
|
+
| // RA = dst*8, RB = table*8, RC = index*8
|
3236
|
+
| decode_RB8a RB, INS
|
3237
|
+
| decode_RB8b RB
|
3238
|
+
| addu CARG2, BASE, RB
|
3239
|
+
| decode_RDtoRC8 RC, RD
|
3240
|
+
| lw CARG1, HI(CARG2)
|
3241
|
+
| li AT, LJ_TTAB
|
3242
|
+
| lw TAB:RB, LO(CARG2)
|
3243
|
+
| addu RA, BASE, RA
|
3244
|
+
| bne CARG1, AT, ->vmeta_tgetb
|
3245
|
+
|. srl TMP0, RC, 3
|
3246
|
+
| lw TMP1, TAB:RB->asize
|
3247
|
+
| lw TMP2, TAB:RB->array
|
3248
|
+
| sltu AT, TMP0, TMP1
|
3249
|
+
| beqz AT, ->vmeta_tgetb
|
3250
|
+
|. addu RC, TMP2, RC
|
3251
|
+
| lw TMP1, HI(RC)
|
3252
|
+
| beq TMP1, TISNIL, >5
|
3253
|
+
|. ldc1 f0, 0(RC)
|
3254
|
+
|1:
|
3255
|
+
| ins_next1
|
3256
|
+
| sdc1 f0, 0(RA)
|
3257
|
+
| ins_next2
|
3258
|
+
|
|
3259
|
+
|5: // Check for __index if table value is nil.
|
3260
|
+
| lw TAB:TMP2, TAB:RB->metatable
|
3261
|
+
| beqz TAB:TMP2, <1 // No metatable: done.
|
3262
|
+
|. nop
|
3263
|
+
| lbu TMP1, TAB:TMP2->nomm
|
3264
|
+
| andi TMP1, TMP1, 1<<MM_index
|
3265
|
+
| bnez TMP1, <1 // 'no __index' flag set: done.
|
3266
|
+
|. nop
|
3267
|
+
| b ->vmeta_tgetb // Caveat: preserve TMP0!
|
3268
|
+
|. nop
|
3269
|
+
break;
|
3270
|
+
case BC_TGETR:
|
3271
|
+
| // RA = dst*8, RB = table*8, RC = key*8
|
3272
|
+
| decode_RB8a RB, INS
|
3273
|
+
| decode_RB8b RB
|
3274
|
+
| decode_RDtoRC8 RC, RD
|
3275
|
+
| addu CARG2, BASE, RB
|
3276
|
+
| addu CARG3, BASE, RC
|
3277
|
+
| lw TAB:CARG1, LO(CARG2)
|
3278
|
+
| ldc1 f0, 0(CARG3)
|
3279
|
+
| trunc.w.d f2, f0
|
3280
|
+
| lw TMP0, TAB:CARG1->asize
|
3281
|
+
| mfc1 CARG2, f2
|
3282
|
+
| lw TMP1, TAB:CARG1->array
|
3283
|
+
| sltu AT, CARG2, TMP0
|
3284
|
+
| sll TMP2, CARG2, 3
|
3285
|
+
| beqz AT, ->vmeta_tgetr // In array part?
|
3286
|
+
|. addu TMP2, TMP1, TMP2
|
3287
|
+
| ldc1 f0, 0(TMP2)
|
3288
|
+
|->BC_TGETR_Z:
|
3289
|
+
| addu RA, BASE, RA
|
3290
|
+
| ins_next1
|
3291
|
+
| sdc1 f0, 0(RA)
|
3292
|
+
| ins_next2
|
3293
|
+
break;
|
3294
|
+
|
3295
|
+
case BC_TSETV:
|
3296
|
+
| // RA = src*8, RB = table*8, RC = key*8
|
3297
|
+
| decode_RB8a RB, INS
|
3298
|
+
| decode_RB8b RB
|
3299
|
+
| decode_RDtoRC8 RC, RD
|
3300
|
+
| addu CARG2, BASE, RB
|
3301
|
+
| addu CARG3, BASE, RC
|
3302
|
+
| lw TMP1, HI(CARG2)
|
3303
|
+
| lw TMP2, HI(CARG3)
|
3304
|
+
| lw TAB:RB, LO(CARG2)
|
3305
|
+
| li AT, LJ_TTAB
|
3306
|
+
| ldc1 f0, 0(CARG3)
|
3307
|
+
| bne TMP1, AT, ->vmeta_tsetv
|
3308
|
+
|. addu RA, BASE, RA
|
3309
|
+
| sltiu AT, TMP2, LJ_TISNUM
|
3310
|
+
| beqz AT, >5
|
3311
|
+
|. li AT, LJ_TSTR
|
3312
|
+
|
|
3313
|
+
| // Convert number key to integer, check for integerness and range.
|
3314
|
+
| cvt.w.d f2, f0
|
3315
|
+
| lw TMP0, TAB:RB->asize
|
3316
|
+
| mfc1 TMP2, f2
|
3317
|
+
| cvt.d.w f4, f2
|
3318
|
+
| lw TMP1, TAB:RB->array
|
3319
|
+
| c.eq.d f0, f4
|
3320
|
+
| sltu AT, TMP2, TMP0
|
3321
|
+
| movf AT, r0
|
3322
|
+
| sll TMP2, TMP2, 3
|
3323
|
+
| beqz AT, ->vmeta_tsetv // Integer key and in array part?
|
3324
|
+
|. addu TMP1, TMP1, TMP2
|
3325
|
+
| lbu TMP3, TAB:RB->marked
|
3326
|
+
| lw TMP0, HI(TMP1)
|
3327
|
+
| beq TMP0, TISNIL, >3
|
3328
|
+
|. ldc1 f0, 0(RA)
|
3329
|
+
|1:
|
3330
|
+
| andi AT, TMP3, LJ_GC_BLACK // isblack(table)
|
3331
|
+
| bnez AT, >7
|
3332
|
+
|. sdc1 f0, 0(TMP1)
|
3333
|
+
|2:
|
3334
|
+
| ins_next
|
3335
|
+
|
|
3336
|
+
|3: // Check for __newindex if previous value is nil.
|
3337
|
+
| lw TAB:TMP2, TAB:RB->metatable
|
3338
|
+
| beqz TAB:TMP2, <1 // No metatable: done.
|
3339
|
+
|. nop
|
3340
|
+
| lbu TMP2, TAB:TMP2->nomm
|
3341
|
+
| andi TMP2, TMP2, 1<<MM_newindex
|
3342
|
+
| bnez TMP2, <1 // 'no __newindex' flag set: done.
|
3343
|
+
|. nop
|
3344
|
+
| b ->vmeta_tsetv
|
3345
|
+
|. nop
|
3346
|
+
|
|
3347
|
+
|5:
|
3348
|
+
| bne TMP2, AT, ->vmeta_tsetv
|
3349
|
+
|. lw STR:RC, LO(CARG3)
|
3350
|
+
| b ->BC_TSETS_Z // String key?
|
3351
|
+
|. nop
|
3352
|
+
|
|
3353
|
+
|7: // Possible table write barrier for the value. Skip valiswhite check.
|
3354
|
+
| barrierback TAB:RB, TMP3, TMP0, <2
|
3355
|
+
break;
|
3356
|
+
case BC_TSETS:
|
3357
|
+
| // RA = src*8, RB = table*8, RC = str_const*8 (~)
|
3358
|
+
| decode_RB8a RB, INS
|
3359
|
+
| decode_RB8b RB
|
3360
|
+
| addu CARG2, BASE, RB
|
3361
|
+
| decode_RC4a RC, INS
|
3362
|
+
| lw TMP0, HI(CARG2)
|
3363
|
+
| decode_RC4b RC
|
3364
|
+
| li AT, LJ_TTAB
|
3365
|
+
| subu CARG3, KBASE, RC
|
3366
|
+
| lw TAB:RB, LO(CARG2)
|
3367
|
+
| lw STR:RC, -4(CARG3) // KBASE-4-str_const*4
|
3368
|
+
| bne TMP0, AT, ->vmeta_tsets1
|
3369
|
+
|. addu RA, BASE, RA
|
3370
|
+
|->BC_TSETS_Z:
|
3371
|
+
| // TAB:RB = GCtab *, STR:RC = GCstr *, RA = BASE+src*8
|
3372
|
+
| lw TMP0, TAB:RB->hmask
|
3373
|
+
| lw TMP1, STR:RC->hash
|
3374
|
+
| lw NODE:TMP2, TAB:RB->node
|
3375
|
+
| sb r0, TAB:RB->nomm // Clear metamethod cache.
|
3376
|
+
| and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask
|
3377
|
+
| sll TMP0, TMP1, 5
|
3378
|
+
| sll TMP1, TMP1, 3
|
3379
|
+
| subu TMP1, TMP0, TMP1
|
3380
|
+
| addu NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8)
|
3381
|
+
| ldc1 f20, 0(RA)
|
3382
|
+
|1:
|
3383
|
+
| lw CARG1, offsetof(Node, key)+HI(NODE:TMP2)
|
3384
|
+
| lw TMP0, offsetof(Node, key)+LO(NODE:TMP2)
|
3385
|
+
| li AT, LJ_TSTR
|
3386
|
+
| lw NODE:TMP1, NODE:TMP2->next
|
3387
|
+
| bne CARG1, AT, >5
|
3388
|
+
|. lw CARG2, offsetof(Node, val)+HI(NODE:TMP2)
|
3389
|
+
| bne TMP0, STR:RC, >5
|
3390
|
+
|. lbu TMP3, TAB:RB->marked
|
3391
|
+
| beq CARG2, TISNIL, >4 // Key found, but nil value?
|
3392
|
+
|. lw TAB:TMP0, TAB:RB->metatable
|
3393
|
+
|2:
|
3394
|
+
| andi AT, TMP3, LJ_GC_BLACK // isblack(table)
|
3395
|
+
| bnez AT, >7
|
3396
|
+
|. sdc1 f20, NODE:TMP2->val
|
3397
|
+
|3:
|
3398
|
+
| ins_next
|
3399
|
+
|
|
3400
|
+
|4: // Check for __newindex if previous value is nil.
|
3401
|
+
| beqz TAB:TMP0, <2 // No metatable: done.
|
3402
|
+
|. nop
|
3403
|
+
| lbu TMP0, TAB:TMP0->nomm
|
3404
|
+
| andi TMP0, TMP0, 1<<MM_newindex
|
3405
|
+
| bnez TMP0, <2 // 'no __newindex' flag set: done.
|
3406
|
+
|. nop
|
3407
|
+
| b ->vmeta_tsets
|
3408
|
+
|. nop
|
3409
|
+
|
|
3410
|
+
|5: // Follow hash chain.
|
3411
|
+
| bnez NODE:TMP1, <1
|
3412
|
+
|. move NODE:TMP2, NODE:TMP1
|
3413
|
+
| // End of hash chain: key not found, add a new one
|
3414
|
+
|
|
3415
|
+
| // But check for __newindex first.
|
3416
|
+
| lw TAB:TMP2, TAB:RB->metatable
|
3417
|
+
| beqz TAB:TMP2, >6 // No metatable: continue.
|
3418
|
+
|. addiu CARG3, DISPATCH, DISPATCH_GL(tmptv)
|
3419
|
+
| lbu TMP0, TAB:TMP2->nomm
|
3420
|
+
| andi TMP0, TMP0, 1<<MM_newindex
|
3421
|
+
| beqz TMP0, ->vmeta_tsets // 'no __newindex' flag NOT set: check.
|
3422
|
+
|. li AT, LJ_TSTR
|
3423
|
+
|6:
|
3424
|
+
| load_got lj_tab_newkey
|
3425
|
+
| sw STR:RC, LO(CARG3)
|
3426
|
+
| sw AT, HI(CARG3)
|
3427
|
+
| sw BASE, L->base
|
3428
|
+
| move CARG2, TAB:RB
|
3429
|
+
| sw PC, SAVE_PC
|
3430
|
+
| call_intern lj_tab_newkey // (lua_State *L, GCtab *t, TValue *k
|
3431
|
+
|. move CARG1, L
|
3432
|
+
| // Returns TValue *.
|
3433
|
+
| lw BASE, L->base
|
3434
|
+
| b <3 // No 2nd write barrier needed.
|
3435
|
+
|. sdc1 f20, 0(CRET1)
|
3436
|
+
|
|
3437
|
+
|7: // Possible table write barrier for the value. Skip valiswhite check.
|
3438
|
+
| barrierback TAB:RB, TMP3, TMP0, <3
|
3439
|
+
break;
|
3440
|
+
case BC_TSETB:
|
3441
|
+
| // RA = src*8, RB = table*8, RC = index*8
|
3442
|
+
| decode_RB8a RB, INS
|
3443
|
+
| decode_RB8b RB
|
3444
|
+
| addu CARG2, BASE, RB
|
3445
|
+
| decode_RDtoRC8 RC, RD
|
3446
|
+
| lw CARG1, HI(CARG2)
|
3447
|
+
| li AT, LJ_TTAB
|
3448
|
+
| lw TAB:RB, LO(CARG2)
|
3449
|
+
| addu RA, BASE, RA
|
3450
|
+
| bne CARG1, AT, ->vmeta_tsetb
|
3451
|
+
|. srl TMP0, RC, 3
|
3452
|
+
| lw TMP1, TAB:RB->asize
|
3453
|
+
| lw TMP2, TAB:RB->array
|
3454
|
+
| sltu AT, TMP0, TMP1
|
3455
|
+
| beqz AT, ->vmeta_tsetb
|
3456
|
+
|. addu RC, TMP2, RC
|
3457
|
+
| lw TMP1, HI(RC)
|
3458
|
+
| lbu TMP3, TAB:RB->marked
|
3459
|
+
| beq TMP1, TISNIL, >5
|
3460
|
+
|. ldc1 f0, 0(RA)
|
3461
|
+
|1:
|
3462
|
+
| andi AT, TMP3, LJ_GC_BLACK // isblack(table)
|
3463
|
+
| bnez AT, >7
|
3464
|
+
|. sdc1 f0, 0(RC)
|
3465
|
+
|2:
|
3466
|
+
| ins_next
|
3467
|
+
|
|
3468
|
+
|5: // Check for __newindex if previous value is nil.
|
3469
|
+
| lw TAB:TMP2, TAB:RB->metatable
|
3470
|
+
| beqz TAB:TMP2, <1 // No metatable: done.
|
3471
|
+
|. nop
|
3472
|
+
| lbu TMP1, TAB:TMP2->nomm
|
3473
|
+
| andi TMP1, TMP1, 1<<MM_newindex
|
3474
|
+
| bnez TMP1, <1 // 'no __newindex' flag set: done.
|
3475
|
+
|. nop
|
3476
|
+
| b ->vmeta_tsetb // Caveat: preserve TMP0!
|
3477
|
+
|. nop
|
3478
|
+
|
|
3479
|
+
|7: // Possible table write barrier for the value. Skip valiswhite check.
|
3480
|
+
| barrierback TAB:RB, TMP3, TMP0, <2
|
3481
|
+
break;
|
3482
|
+
case BC_TSETR:
|
3483
|
+
| // RA = dst*8, RB = table*8, RC = key*8
|
3484
|
+
| decode_RB8a RB, INS
|
3485
|
+
| decode_RB8b RB
|
3486
|
+
| decode_RDtoRC8 RC, RD
|
3487
|
+
| addu CARG1, BASE, RB
|
3488
|
+
| addu CARG3, BASE, RC
|
3489
|
+
| lw TAB:CARG2, LO(CARG1)
|
3490
|
+
| ldc1 f0, 0(CARG3)
|
3491
|
+
| trunc.w.d f2, f0
|
3492
|
+
| lbu TMP3, TAB:CARG2->marked
|
3493
|
+
| lw TMP0, TAB:CARG2->asize
|
3494
|
+
| mfc1 CARG3, f2
|
3495
|
+
| lw TMP1, TAB:CARG2->array
|
3496
|
+
| andi AT, TMP3, LJ_GC_BLACK // isblack(table)
|
3497
|
+
| bnez AT, >7
|
3498
|
+
|. addu RA, BASE, RA
|
3499
|
+
|2:
|
3500
|
+
| sltu AT, CARG3, TMP0
|
3501
|
+
| sll TMP2, CARG3, 3
|
3502
|
+
| beqz AT, ->vmeta_tsetr // In array part?
|
3503
|
+
|. ldc1 f20, 0(RA)
|
3504
|
+
| addu CRET1, TMP1, TMP2
|
3505
|
+
|->BC_TSETR_Z:
|
3506
|
+
| ins_next1
|
3507
|
+
| sdc1 f20, 0(CRET1)
|
3508
|
+
| ins_next2
|
3509
|
+
|
|
3510
|
+
|7: // Possible table write barrier for the value. Skip valiswhite check.
|
3511
|
+
| barrierback TAB:RB, TMP3, TMP0, <2
|
3512
|
+
break;
|
3513
|
+
|
3514
|
+
|
3515
|
+
case BC_TSETM:
|
3516
|
+
| // RA = base*8 (table at base-1), RD = num_const*8 (start index)
|
3517
|
+
| addu RA, BASE, RA
|
3518
|
+
|1:
|
3519
|
+
| addu TMP3, KBASE, RD
|
3520
|
+
| lw TAB:CARG2, -8+LO(RA) // Guaranteed to be a table.
|
3521
|
+
| addiu TMP0, MULTRES, -8
|
3522
|
+
| lw TMP3, LO(TMP3) // Integer constant is in lo-word.
|
3523
|
+
| beqz TMP0, >4 // Nothing to copy?
|
3524
|
+
|. srl CARG3, TMP0, 3
|
3525
|
+
| addu CARG3, CARG3, TMP3
|
3526
|
+
| lw TMP2, TAB:CARG2->asize
|
3527
|
+
| sll TMP1, TMP3, 3
|
3528
|
+
| lbu TMP3, TAB:CARG2->marked
|
3529
|
+
| lw CARG1, TAB:CARG2->array
|
3530
|
+
| sltu AT, TMP2, CARG3
|
3531
|
+
| bnez AT, >5
|
3532
|
+
|. addu TMP2, RA, TMP0
|
3533
|
+
| addu TMP1, TMP1, CARG1
|
3534
|
+
| andi TMP0, TMP3, LJ_GC_BLACK // isblack(table)
|
3535
|
+
|3: // Copy result slots to table.
|
3536
|
+
| ldc1 f0, 0(RA)
|
3537
|
+
| addiu RA, RA, 8
|
3538
|
+
| sltu AT, RA, TMP2
|
3539
|
+
| sdc1 f0, 0(TMP1)
|
3540
|
+
| bnez AT, <3
|
3541
|
+
|. addiu TMP1, TMP1, 8
|
3542
|
+
| bnez TMP0, >7
|
3543
|
+
|. nop
|
3544
|
+
|4:
|
3545
|
+
| ins_next
|
3546
|
+
|
|
3547
|
+
|5: // Need to resize array part.
|
3548
|
+
| load_got lj_tab_reasize
|
3549
|
+
| sw BASE, L->base
|
3550
|
+
| sw PC, SAVE_PC
|
3551
|
+
| move BASE, RD
|
3552
|
+
| call_intern lj_tab_reasize // (lua_State *L, GCtab *t, int nasize)
|
3553
|
+
|. move CARG1, L
|
3554
|
+
| // Must not reallocate the stack.
|
3555
|
+
| move RD, BASE
|
3556
|
+
| b <1
|
3557
|
+
|. lw BASE, L->base // Reload BASE for lack of a saved register.
|
3558
|
+
|
|
3559
|
+
|7: // Possible table write barrier for any value. Skip valiswhite check.
|
3560
|
+
| barrierback TAB:CARG2, TMP3, TMP0, <4
|
3561
|
+
break;
|
3562
|
+
|
3563
|
+
/* -- Calls and vararg handling ----------------------------------------- */
|
3564
|
+
|
3565
|
+
case BC_CALLM:
|
3566
|
+
| // RA = base*8, (RB = (nresults+1)*8,) RC = extra_nargs*8
|
3567
|
+
| decode_RDtoRC8 NARGS8:RC, RD
|
3568
|
+
| b ->BC_CALL_Z
|
3569
|
+
|. addu NARGS8:RC, NARGS8:RC, MULTRES
|
3570
|
+
break;
|
3571
|
+
case BC_CALL:
|
3572
|
+
| // RA = base*8, (RB = (nresults+1)*8,) RC = (nargs+1)*8
|
3573
|
+
| decode_RDtoRC8 NARGS8:RC, RD
|
3574
|
+
|->BC_CALL_Z:
|
3575
|
+
| move TMP2, BASE
|
3576
|
+
| addu BASE, BASE, RA
|
3577
|
+
| li AT, LJ_TFUNC
|
3578
|
+
| lw TMP0, HI(BASE)
|
3579
|
+
| lw LFUNC:RB, LO(BASE)
|
3580
|
+
| addiu BASE, BASE, 8
|
3581
|
+
| bne TMP0, AT, ->vmeta_call
|
3582
|
+
|. addiu NARGS8:RC, NARGS8:RC, -8
|
3583
|
+
| ins_call
|
3584
|
+
break;
|
3585
|
+
|
3586
|
+
case BC_CALLMT:
|
3587
|
+
| // RA = base*8, (RB = 0,) RC = extra_nargs*8
|
3588
|
+
| addu NARGS8:RD, NARGS8:RD, MULTRES // BC_CALLT gets RC from RD.
|
3589
|
+
| // Fall through. Assumes BC_CALLT follows.
|
3590
|
+
break;
|
3591
|
+
case BC_CALLT:
|
3592
|
+
| // RA = base*8, (RB = 0,) RC = (nargs+1)*8
|
3593
|
+
| addu RA, BASE, RA
|
3594
|
+
| li AT, LJ_TFUNC
|
3595
|
+
| lw TMP0, HI(RA)
|
3596
|
+
| lw LFUNC:RB, LO(RA)
|
3597
|
+
| move NARGS8:RC, RD
|
3598
|
+
| lw TMP1, FRAME_PC(BASE)
|
3599
|
+
| addiu RA, RA, 8
|
3600
|
+
| bne TMP0, AT, ->vmeta_callt
|
3601
|
+
|. addiu NARGS8:RC, NARGS8:RC, -8
|
3602
|
+
|->BC_CALLT_Z:
|
3603
|
+
| andi TMP0, TMP1, FRAME_TYPE // Caveat: preserve TMP0 until the 'or'.
|
3604
|
+
| lbu TMP3, LFUNC:RB->ffid
|
3605
|
+
| bnez TMP0, >7
|
3606
|
+
|. xori TMP2, TMP1, FRAME_VARG
|
3607
|
+
|1:
|
3608
|
+
| sw LFUNC:RB, FRAME_FUNC(BASE) // Copy function down, but keep PC.
|
3609
|
+
| sltiu AT, TMP3, 2 // (> FF_C) Calling a fast function?
|
3610
|
+
| move TMP2, BASE
|
3611
|
+
| beqz NARGS8:RC, >3
|
3612
|
+
|. move TMP3, NARGS8:RC
|
3613
|
+
|2:
|
3614
|
+
| ldc1 f0, 0(RA)
|
3615
|
+
| addiu RA, RA, 8
|
3616
|
+
| addiu TMP3, TMP3, -8
|
3617
|
+
| sdc1 f0, 0(TMP2)
|
3618
|
+
| bnez TMP3, <2
|
3619
|
+
|. addiu TMP2, TMP2, 8
|
3620
|
+
|3:
|
3621
|
+
| or TMP0, TMP0, AT
|
3622
|
+
| beqz TMP0, >5
|
3623
|
+
|. nop
|
3624
|
+
|4:
|
3625
|
+
| ins_callt
|
3626
|
+
|
|
3627
|
+
|5: // Tailcall to a fast function with a Lua frame below.
|
3628
|
+
| lw INS, -4(TMP1)
|
3629
|
+
| decode_RA8a RA, INS
|
3630
|
+
| decode_RA8b RA
|
3631
|
+
| subu TMP1, BASE, RA
|
3632
|
+
| lw LFUNC:TMP1, -8+FRAME_FUNC(TMP1)
|
3633
|
+
| lw TMP1, LFUNC:TMP1->pc
|
3634
|
+
| b <4
|
3635
|
+
|. lw KBASE, PC2PROTO(k)(TMP1) // Need to prepare KBASE.
|
3636
|
+
|
|
3637
|
+
|7: // Tailcall from a vararg function.
|
3638
|
+
| andi AT, TMP2, FRAME_TYPEP
|
3639
|
+
| bnez AT, <1 // Vararg frame below?
|
3640
|
+
|. subu TMP2, BASE, TMP2 // Relocate BASE down.
|
3641
|
+
| move BASE, TMP2
|
3642
|
+
| lw TMP1, FRAME_PC(TMP2)
|
3643
|
+
| b <1
|
3644
|
+
|. andi TMP0, TMP1, FRAME_TYPE
|
3645
|
+
break;
|
3646
|
+
|
3647
|
+
case BC_ITERC:
|
3648
|
+
| // RA = base*8, (RB = (nresults+1)*8, RC = (nargs+1)*8 ((2+1)*8))
|
3649
|
+
| move TMP2, BASE
|
3650
|
+
| addu BASE, BASE, RA
|
3651
|
+
| li AT, LJ_TFUNC
|
3652
|
+
| lw TMP1, -24+HI(BASE)
|
3653
|
+
| lw LFUNC:RB, -24+LO(BASE)
|
3654
|
+
| ldc1 f2, -8(BASE)
|
3655
|
+
| ldc1 f0, -16(BASE)
|
3656
|
+
| sw TMP1, HI(BASE) // Copy callable.
|
3657
|
+
| sw LFUNC:RB, LO(BASE)
|
3658
|
+
| sdc1 f2, 16(BASE) // Copy control var.
|
3659
|
+
| sdc1 f0, 8(BASE) // Copy state.
|
3660
|
+
| addiu BASE, BASE, 8
|
3661
|
+
| bne TMP1, AT, ->vmeta_call
|
3662
|
+
|. li NARGS8:RC, 16 // Iterators get 2 arguments.
|
3663
|
+
| ins_call
|
3664
|
+
break;
|
3665
|
+
|
3666
|
+
case BC_ITERN:
|
3667
|
+
| // RA = base*8, (RB = (nresults+1)*8, RC = (nargs+1)*8 (2+1)*8)
|
3668
|
+
|.if JIT
|
3669
|
+
| // NYI: add hotloop, record BC_ITERN.
|
3670
|
+
|.endif
|
3671
|
+
| addu RA, BASE, RA
|
3672
|
+
| lw TAB:RB, -16+LO(RA)
|
3673
|
+
| lw RC, -8+LO(RA) // Get index from control var.
|
3674
|
+
| lw TMP0, TAB:RB->asize
|
3675
|
+
| lw TMP1, TAB:RB->array
|
3676
|
+
| addiu PC, PC, 4
|
3677
|
+
|1: // Traverse array part.
|
3678
|
+
| sltu AT, RC, TMP0
|
3679
|
+
| beqz AT, >5 // Index points after array part?
|
3680
|
+
|. sll TMP3, RC, 3
|
3681
|
+
| addu TMP3, TMP1, TMP3
|
3682
|
+
| lw TMP2, HI(TMP3)
|
3683
|
+
| ldc1 f0, 0(TMP3)
|
3684
|
+
| mtc1 RC, f2
|
3685
|
+
| lhu RD, -4+OFS_RD(PC)
|
3686
|
+
| beq TMP2, TISNIL, <1 // Skip holes in array part.
|
3687
|
+
|. addiu RC, RC, 1
|
3688
|
+
| cvt.d.w f2, f2
|
3689
|
+
| lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535)
|
3690
|
+
| sdc1 f0, 8(RA)
|
3691
|
+
| decode_RD4b RD
|
3692
|
+
| addu RD, RD, TMP3
|
3693
|
+
| sw RC, -8+LO(RA) // Update control var.
|
3694
|
+
| addu PC, PC, RD
|
3695
|
+
| sdc1 f2, 0(RA)
|
3696
|
+
|3:
|
3697
|
+
| ins_next
|
3698
|
+
|
|
3699
|
+
|5: // Traverse hash part.
|
3700
|
+
| lw TMP1, TAB:RB->hmask
|
3701
|
+
| subu RC, RC, TMP0
|
3702
|
+
| lw TMP2, TAB:RB->node
|
3703
|
+
|6:
|
3704
|
+
| sltu AT, TMP1, RC // End of iteration? Branch to ITERL+1.
|
3705
|
+
| bnez AT, <3
|
3706
|
+
|. sll TMP3, RC, 5
|
3707
|
+
| sll RB, RC, 3
|
3708
|
+
| subu TMP3, TMP3, RB
|
3709
|
+
| addu NODE:TMP3, TMP3, TMP2
|
3710
|
+
| lw RB, HI(NODE:TMP3)
|
3711
|
+
| ldc1 f0, 0(NODE:TMP3)
|
3712
|
+
| lhu RD, -4+OFS_RD(PC)
|
3713
|
+
| beq RB, TISNIL, <6 // Skip holes in hash part.
|
3714
|
+
|. addiu RC, RC, 1
|
3715
|
+
| ldc1 f2, NODE:TMP3->key
|
3716
|
+
| lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535)
|
3717
|
+
| sdc1 f0, 8(RA)
|
3718
|
+
| addu RC, RC, TMP0
|
3719
|
+
| decode_RD4b RD
|
3720
|
+
| addu RD, RD, TMP3
|
3721
|
+
| sdc1 f2, 0(RA)
|
3722
|
+
| addu PC, PC, RD
|
3723
|
+
| b <3
|
3724
|
+
|. sw RC, -8+LO(RA) // Update control var.
|
3725
|
+
break;
|
3726
|
+
|
3727
|
+
case BC_ISNEXT:
|
3728
|
+
| // RA = base*8, RD = target (points to ITERN)
|
3729
|
+
| addu RA, BASE, RA
|
3730
|
+
| lw TMP0, -24+HI(RA)
|
3731
|
+
| lw CFUNC:TMP1, -24+LO(RA)
|
3732
|
+
| lw TMP2, -16+HI(RA)
|
3733
|
+
| lw TMP3, -8+HI(RA)
|
3734
|
+
| li AT, LJ_TFUNC
|
3735
|
+
| bne TMP0, AT, >5
|
3736
|
+
|. addiu TMP2, TMP2, -LJ_TTAB
|
3737
|
+
| lbu TMP1, CFUNC:TMP1->ffid
|
3738
|
+
| addiu TMP3, TMP3, -LJ_TNIL
|
3739
|
+
| srl TMP0, RD, 1
|
3740
|
+
| or TMP2, TMP2, TMP3
|
3741
|
+
| addiu TMP1, TMP1, -FF_next_N
|
3742
|
+
| addu TMP0, PC, TMP0
|
3743
|
+
| or TMP1, TMP1, TMP2
|
3744
|
+
| bnez TMP1, >5
|
3745
|
+
|. lui TMP2, (-(BCBIAS_J*4 >> 16) & 65535)
|
3746
|
+
| addu PC, TMP0, TMP2
|
3747
|
+
| lui TMP1, 0xfffe
|
3748
|
+
| ori TMP1, TMP1, 0x7fff
|
3749
|
+
| sw r0, -8+LO(RA) // Initialize control var.
|
3750
|
+
| sw TMP1, -8+HI(RA)
|
3751
|
+
|1:
|
3752
|
+
| ins_next
|
3753
|
+
|5: // Despecialize bytecode if any of the checks fail.
|
3754
|
+
| li TMP3, BC_JMP
|
3755
|
+
| li TMP1, BC_ITERC
|
3756
|
+
| sb TMP3, -4+OFS_OP(PC)
|
3757
|
+
| addu PC, TMP0, TMP2
|
3758
|
+
| b <1
|
3759
|
+
|. sb TMP1, OFS_OP(PC)
|
3760
|
+
break;
|
3761
|
+
|
3762
|
+
case BC_VARG:
|
3763
|
+
| // RA = base*8, RB = (nresults+1)*8, RC = numparams*8
|
3764
|
+
| lw TMP0, FRAME_PC(BASE)
|
3765
|
+
| decode_RDtoRC8 RC, RD
|
3766
|
+
| decode_RB8a RB, INS
|
3767
|
+
| addu RC, BASE, RC
|
3768
|
+
| decode_RB8b RB
|
3769
|
+
| addu RA, BASE, RA
|
3770
|
+
| addiu RC, RC, FRAME_VARG
|
3771
|
+
| addu TMP2, RA, RB
|
3772
|
+
| addiu TMP3, BASE, -8 // TMP3 = vtop
|
3773
|
+
| subu RC, RC, TMP0 // RC = vbase
|
3774
|
+
| // Note: RC may now be even _above_ BASE if nargs was < numparams.
|
3775
|
+
| beqz RB, >5 // Copy all varargs?
|
3776
|
+
|. subu TMP1, TMP3, RC
|
3777
|
+
| addiu TMP2, TMP2, -16
|
3778
|
+
|1: // Copy vararg slots to destination slots.
|
3779
|
+
| lw CARG1, HI(RC)
|
3780
|
+
| sltu AT, RC, TMP3
|
3781
|
+
| lw CARG2, LO(RC)
|
3782
|
+
| addiu RC, RC, 8
|
3783
|
+
| movz CARG1, TISNIL, AT
|
3784
|
+
| sw CARG1, HI(RA)
|
3785
|
+
| sw CARG2, LO(RA)
|
3786
|
+
| sltu AT, RA, TMP2
|
3787
|
+
| bnez AT, <1
|
3788
|
+
|. addiu RA, RA, 8
|
3789
|
+
|3:
|
3790
|
+
| ins_next
|
3791
|
+
|
|
3792
|
+
|5: // Copy all varargs.
|
3793
|
+
| lw TMP0, L->maxstack
|
3794
|
+
| blez TMP1, <3 // No vararg slots?
|
3795
|
+
|. li MULTRES, 8 // MULTRES = (0+1)*8
|
3796
|
+
| addu TMP2, RA, TMP1
|
3797
|
+
| sltu AT, TMP0, TMP2
|
3798
|
+
| bnez AT, >7
|
3799
|
+
|. addiu MULTRES, TMP1, 8
|
3800
|
+
|6:
|
3801
|
+
| ldc1 f0, 0(RC)
|
3802
|
+
| addiu RC, RC, 8
|
3803
|
+
| sdc1 f0, 0(RA)
|
3804
|
+
| sltu AT, RC, TMP3
|
3805
|
+
| bnez AT, <6 // More vararg slots?
|
3806
|
+
|. addiu RA, RA, 8
|
3807
|
+
| b <3
|
3808
|
+
|. nop
|
3809
|
+
|
|
3810
|
+
|7: // Grow stack for varargs.
|
3811
|
+
| load_got lj_state_growstack
|
3812
|
+
| sw RA, L->top
|
3813
|
+
| subu RA, RA, BASE
|
3814
|
+
| sw BASE, L->base
|
3815
|
+
| subu BASE, RC, BASE // Need delta, because BASE may change.
|
3816
|
+
| sw PC, SAVE_PC
|
3817
|
+
| srl CARG2, TMP1, 3
|
3818
|
+
| call_intern lj_state_growstack // (lua_State *L, int n)
|
3819
|
+
|. move CARG1, L
|
3820
|
+
| move RC, BASE
|
3821
|
+
| lw BASE, L->base
|
3822
|
+
| addu RA, BASE, RA
|
3823
|
+
| addu RC, BASE, RC
|
3824
|
+
| b <6
|
3825
|
+
|. addiu TMP3, BASE, -8
|
3826
|
+
break;
|
3827
|
+
|
3828
|
+
/* -- Returns ----------------------------------------------------------- */
|
3829
|
+
|
3830
|
+
case BC_RETM:
|
3831
|
+
| // RA = results*8, RD = extra_nresults*8
|
3832
|
+
| addu RD, RD, MULTRES // MULTRES >= 8, so RD >= 8.
|
3833
|
+
| // Fall through. Assumes BC_RET follows.
|
3834
|
+
break;
|
3835
|
+
|
3836
|
+
case BC_RET:
|
3837
|
+
| // RA = results*8, RD = (nresults+1)*8
|
3838
|
+
| lw PC, FRAME_PC(BASE)
|
3839
|
+
| addu RA, BASE, RA
|
3840
|
+
| move MULTRES, RD
|
3841
|
+
|1:
|
3842
|
+
| andi TMP0, PC, FRAME_TYPE
|
3843
|
+
| bnez TMP0, ->BC_RETV_Z
|
3844
|
+
|. xori TMP1, PC, FRAME_VARG
|
3845
|
+
|
|
3846
|
+
|->BC_RET_Z:
|
3847
|
+
| // BASE = base, RA = resultptr, RD = (nresults+1)*8, PC = return
|
3848
|
+
| lw INS, -4(PC)
|
3849
|
+
| addiu TMP2, BASE, -8
|
3850
|
+
| addiu RC, RD, -8
|
3851
|
+
| decode_RA8a TMP0, INS
|
3852
|
+
| decode_RB8a RB, INS
|
3853
|
+
| decode_RA8b TMP0
|
3854
|
+
| decode_RB8b RB
|
3855
|
+
| addu TMP3, TMP2, RB
|
3856
|
+
| beqz RC, >3
|
3857
|
+
|. subu BASE, TMP2, TMP0
|
3858
|
+
|2:
|
3859
|
+
| ldc1 f0, 0(RA)
|
3860
|
+
| addiu RA, RA, 8
|
3861
|
+
| addiu RC, RC, -8
|
3862
|
+
| sdc1 f0, 0(TMP2)
|
3863
|
+
| bnez RC, <2
|
3864
|
+
|. addiu TMP2, TMP2, 8
|
3865
|
+
|3:
|
3866
|
+
| addiu TMP3, TMP3, -8
|
3867
|
+
|5:
|
3868
|
+
| sltu AT, TMP2, TMP3
|
3869
|
+
| bnez AT, >6
|
3870
|
+
|. lw LFUNC:TMP1, FRAME_FUNC(BASE)
|
3871
|
+
| ins_next1
|
3872
|
+
| lw TMP1, LFUNC:TMP1->pc
|
3873
|
+
| lw KBASE, PC2PROTO(k)(TMP1)
|
3874
|
+
| ins_next2
|
3875
|
+
|
|
3876
|
+
|6: // Fill up results with nil.
|
3877
|
+
| sw TISNIL, HI(TMP2)
|
3878
|
+
| b <5
|
3879
|
+
|. addiu TMP2, TMP2, 8
|
3880
|
+
|
|
3881
|
+
|->BC_RETV_Z: // Non-standard return case.
|
3882
|
+
| andi TMP2, TMP1, FRAME_TYPEP
|
3883
|
+
| bnez TMP2, ->vm_return
|
3884
|
+
|. nop
|
3885
|
+
| // Return from vararg function: relocate BASE down.
|
3886
|
+
| subu BASE, BASE, TMP1
|
3887
|
+
| b <1
|
3888
|
+
|. lw PC, FRAME_PC(BASE)
|
3889
|
+
break;
|
3890
|
+
|
3891
|
+
case BC_RET0: case BC_RET1:
|
3892
|
+
| // RA = results*8, RD = (nresults+1)*8
|
3893
|
+
| lw PC, FRAME_PC(BASE)
|
3894
|
+
| addu RA, BASE, RA
|
3895
|
+
| move MULTRES, RD
|
3896
|
+
| andi TMP0, PC, FRAME_TYPE
|
3897
|
+
| bnez TMP0, ->BC_RETV_Z
|
3898
|
+
|. xori TMP1, PC, FRAME_VARG
|
3899
|
+
|
|
3900
|
+
| lw INS, -4(PC)
|
3901
|
+
| addiu TMP2, BASE, -8
|
3902
|
+
if (op == BC_RET1) {
|
3903
|
+
| ldc1 f0, 0(RA)
|
3904
|
+
}
|
3905
|
+
| decode_RB8a RB, INS
|
3906
|
+
| decode_RA8a RA, INS
|
3907
|
+
| decode_RB8b RB
|
3908
|
+
| decode_RA8b RA
|
3909
|
+
if (op == BC_RET1) {
|
3910
|
+
| sdc1 f0, 0(TMP2)
|
3911
|
+
}
|
3912
|
+
| subu BASE, TMP2, RA
|
3913
|
+
|5:
|
3914
|
+
| sltu AT, RD, RB
|
3915
|
+
| bnez AT, >6
|
3916
|
+
|. lw LFUNC:TMP1, FRAME_FUNC(BASE)
|
3917
|
+
| ins_next1
|
3918
|
+
| lw TMP1, LFUNC:TMP1->pc
|
3919
|
+
| lw KBASE, PC2PROTO(k)(TMP1)
|
3920
|
+
| ins_next2
|
3921
|
+
|
|
3922
|
+
|6: // Fill up results with nil.
|
3923
|
+
| addiu TMP2, TMP2, 8
|
3924
|
+
| addiu RD, RD, 8
|
3925
|
+
| b <5
|
3926
|
+
if (op == BC_RET1) {
|
3927
|
+
|. sw TISNIL, HI(TMP2)
|
3928
|
+
} else {
|
3929
|
+
|. sw TISNIL, -8+HI(TMP2)
|
3930
|
+
}
|
3931
|
+
break;
|
3932
|
+
|
3933
|
+
/* -- Loops and branches ------------------------------------------------ */
|
3934
|
+
|
3935
|
+
case BC_FORL:
|
3936
|
+
|.if JIT
|
3937
|
+
| hotloop
|
3938
|
+
|.endif
|
3939
|
+
| // Fall through. Assumes BC_IFORL follows.
|
3940
|
+
break;
|
3941
|
+
|
3942
|
+
case BC_JFORI:
|
3943
|
+
case BC_JFORL:
|
3944
|
+
#if !LJ_HASJIT
|
3945
|
+
break;
|
3946
|
+
#endif
|
3947
|
+
case BC_FORI:
|
3948
|
+
case BC_IFORL:
|
3949
|
+
| // RA = base*8, RD = target (after end of loop or start of loop)
|
3950
|
+
vk = (op == BC_IFORL || op == BC_JFORL);
|
3951
|
+
| addu RA, BASE, RA
|
3952
|
+
if (vk) {
|
3953
|
+
| ldc1 f0, FORL_IDX*8(RA)
|
3954
|
+
| ldc1 f4, FORL_STEP*8(RA)
|
3955
|
+
| ldc1 f2, FORL_STOP*8(RA)
|
3956
|
+
| lw TMP3, FORL_STEP*8+HI(RA)
|
3957
|
+
| add.d f0, f0, f4
|
3958
|
+
| sdc1 f0, FORL_IDX*8(RA)
|
3959
|
+
} else {
|
3960
|
+
| lw TMP1, FORL_IDX*8+HI(RA)
|
3961
|
+
| lw TMP3, FORL_STEP*8+HI(RA)
|
3962
|
+
| lw TMP2, FORL_STOP*8+HI(RA)
|
3963
|
+
| sltiu TMP1, TMP1, LJ_TISNUM
|
3964
|
+
| sltiu TMP0, TMP3, LJ_TISNUM
|
3965
|
+
| sltiu TMP2, TMP2, LJ_TISNUM
|
3966
|
+
| and TMP1, TMP1, TMP0
|
3967
|
+
| and TMP1, TMP1, TMP2
|
3968
|
+
| ldc1 f0, FORL_IDX*8(RA)
|
3969
|
+
| beqz TMP1, ->vmeta_for
|
3970
|
+
|. ldc1 f2, FORL_STOP*8(RA)
|
3971
|
+
}
|
3972
|
+
if (op != BC_JFORL) {
|
3973
|
+
| srl RD, RD, 1
|
3974
|
+
| lui TMP0, (-(BCBIAS_J*4 >> 16) & 65535)
|
3975
|
+
}
|
3976
|
+
| c.le.d 0, f0, f2
|
3977
|
+
| c.le.d 1, f2, f0
|
3978
|
+
| sdc1 f0, FORL_EXT*8(RA)
|
3979
|
+
if (op == BC_JFORI) {
|
3980
|
+
| li TMP1, 1
|
3981
|
+
| li TMP2, 1
|
3982
|
+
| addu TMP0, RD, TMP0
|
3983
|
+
| slt TMP3, TMP3, r0
|
3984
|
+
| movf TMP1, r0, 0
|
3985
|
+
| addu PC, PC, TMP0
|
3986
|
+
| movf TMP2, r0, 1
|
3987
|
+
| lhu RD, -4+OFS_RD(PC)
|
3988
|
+
| movn TMP1, TMP2, TMP3
|
3989
|
+
| bnez TMP1, =>BC_JLOOP
|
3990
|
+
|. decode_RD8b RD
|
3991
|
+
} else if (op == BC_JFORL) {
|
3992
|
+
| li TMP1, 1
|
3993
|
+
| li TMP2, 1
|
3994
|
+
| slt TMP3, TMP3, r0
|
3995
|
+
| movf TMP1, r0, 0
|
3996
|
+
| movf TMP2, r0, 1
|
3997
|
+
| movn TMP1, TMP2, TMP3
|
3998
|
+
| bnez TMP1, =>BC_JLOOP
|
3999
|
+
|. nop
|
4000
|
+
} else {
|
4001
|
+
| addu TMP1, RD, TMP0
|
4002
|
+
| slt TMP3, TMP3, r0
|
4003
|
+
| move TMP2, TMP1
|
4004
|
+
if (op == BC_FORI) {
|
4005
|
+
| movt TMP1, r0, 0
|
4006
|
+
| movt TMP2, r0, 1
|
4007
|
+
} else {
|
4008
|
+
| movf TMP1, r0, 0
|
4009
|
+
| movf TMP2, r0, 1
|
4010
|
+
}
|
4011
|
+
| movn TMP1, TMP2, TMP3
|
4012
|
+
| addu PC, PC, TMP1
|
4013
|
+
}
|
4014
|
+
| ins_next
|
4015
|
+
break;
|
4016
|
+
|
4017
|
+
case BC_ITERL:
|
4018
|
+
|.if JIT
|
4019
|
+
| hotloop
|
4020
|
+
|.endif
|
4021
|
+
| // Fall through. Assumes BC_IITERL follows.
|
4022
|
+
break;
|
4023
|
+
|
4024
|
+
case BC_JITERL:
|
4025
|
+
#if !LJ_HASJIT
|
4026
|
+
break;
|
4027
|
+
#endif
|
4028
|
+
case BC_IITERL:
|
4029
|
+
| // RA = base*8, RD = target
|
4030
|
+
| addu RA, BASE, RA
|
4031
|
+
| lw TMP1, HI(RA)
|
4032
|
+
| beq TMP1, TISNIL, >1 // Stop if iterator returned nil.
|
4033
|
+
|. lw TMP2, LO(RA)
|
4034
|
+
if (op == BC_JITERL) {
|
4035
|
+
| sw TMP1, -8+HI(RA)
|
4036
|
+
| b =>BC_JLOOP
|
4037
|
+
|. sw TMP2, -8+LO(RA)
|
4038
|
+
} else {
|
4039
|
+
| branch_RD // Otherwise save control var + branch.
|
4040
|
+
| sw TMP1, -8+HI(RA)
|
4041
|
+
| sw TMP2, -8+LO(RA)
|
4042
|
+
}
|
4043
|
+
|1:
|
4044
|
+
| ins_next
|
4045
|
+
break;
|
4046
|
+
|
4047
|
+
case BC_LOOP:
|
4048
|
+
| // RA = base*8, RD = target (loop extent)
|
4049
|
+
| // Note: RA/RD is only used by trace recorder to determine scope/extent
|
4050
|
+
| // This opcode does NOT jump, it's only purpose is to detect a hot loop.
|
4051
|
+
|.if JIT
|
4052
|
+
| hotloop
|
4053
|
+
|.endif
|
4054
|
+
| // Fall through. Assumes BC_ILOOP follows.
|
4055
|
+
break;
|
4056
|
+
|
4057
|
+
case BC_ILOOP:
|
4058
|
+
| // RA = base*8, RD = target (loop extent)
|
4059
|
+
| ins_next
|
4060
|
+
break;
|
4061
|
+
|
4062
|
+
case BC_JLOOP:
|
4063
|
+
|.if JIT
|
4064
|
+
| // RA = base*8 (ignored), RD = traceno*8
|
4065
|
+
| lw TMP1, DISPATCH_J(trace)(DISPATCH)
|
4066
|
+
| srl RD, RD, 1
|
4067
|
+
| li AT, 0
|
4068
|
+
| addu TMP1, TMP1, RD
|
4069
|
+
| // Traces on MIPS don't store the trace number, so use 0.
|
4070
|
+
| sw AT, DISPATCH_GL(vmstate)(DISPATCH)
|
4071
|
+
| lw TRACE:TMP2, 0(TMP1)
|
4072
|
+
| sw BASE, DISPATCH_GL(jit_base)(DISPATCH)
|
4073
|
+
| lw TMP2, TRACE:TMP2->mcode
|
4074
|
+
| sw L, DISPATCH_GL(tmpbuf.L)(DISPATCH)
|
4075
|
+
| jr TMP2
|
4076
|
+
|. addiu JGL, DISPATCH, GG_DISP2G+32768
|
4077
|
+
|.endif
|
4078
|
+
break;
|
4079
|
+
|
4080
|
+
case BC_JMP:
|
4081
|
+
| // RA = base*8 (only used by trace recorder), RD = target
|
4082
|
+
| branch_RD
|
4083
|
+
| ins_next
|
4084
|
+
break;
|
4085
|
+
|
4086
|
+
/* -- Function headers -------------------------------------------------- */
|
4087
|
+
|
4088
|
+
case BC_FUNCF:
|
4089
|
+
|.if JIT
|
4090
|
+
| hotcall
|
4091
|
+
|.endif
|
4092
|
+
case BC_FUNCV: /* NYI: compiled vararg functions. */
|
4093
|
+
| // Fall through. Assumes BC_IFUNCF/BC_IFUNCV follow.
|
4094
|
+
break;
|
4095
|
+
|
4096
|
+
case BC_JFUNCF:
|
4097
|
+
#if !LJ_HASJIT
|
4098
|
+
break;
|
4099
|
+
#endif
|
4100
|
+
case BC_IFUNCF:
|
4101
|
+
| // BASE = new base, RA = BASE+framesize*8, RB = LFUNC, RC = nargs*8
|
4102
|
+
| lw TMP2, L->maxstack
|
4103
|
+
| lbu TMP1, -4+PC2PROTO(numparams)(PC)
|
4104
|
+
| lw KBASE, -4+PC2PROTO(k)(PC)
|
4105
|
+
| sltu AT, TMP2, RA
|
4106
|
+
| bnez AT, ->vm_growstack_l
|
4107
|
+
|. sll TMP1, TMP1, 3
|
4108
|
+
if (op != BC_JFUNCF) {
|
4109
|
+
| ins_next1
|
4110
|
+
}
|
4111
|
+
|2:
|
4112
|
+
| sltu AT, NARGS8:RC, TMP1 // Check for missing parameters.
|
4113
|
+
| bnez AT, >3
|
4114
|
+
|. addu AT, BASE, NARGS8:RC
|
4115
|
+
if (op == BC_JFUNCF) {
|
4116
|
+
| decode_RD8a RD, INS
|
4117
|
+
| b =>BC_JLOOP
|
4118
|
+
|. decode_RD8b RD
|
4119
|
+
} else {
|
4120
|
+
| ins_next2
|
4121
|
+
}
|
4122
|
+
|
|
4123
|
+
|3: // Clear missing parameters.
|
4124
|
+
| sw TISNIL, HI(AT)
|
4125
|
+
| b <2
|
4126
|
+
|. addiu NARGS8:RC, NARGS8:RC, 8
|
4127
|
+
break;
|
4128
|
+
|
4129
|
+
case BC_JFUNCV:
|
4130
|
+
#if !LJ_HASJIT
|
4131
|
+
break;
|
4132
|
+
#endif
|
4133
|
+
| NYI // NYI: compiled vararg functions
|
4134
|
+
break; /* NYI: compiled vararg functions. */
|
4135
|
+
|
4136
|
+
case BC_IFUNCV:
|
4137
|
+
| // BASE = new base, RA = BASE+framesize*8, RB = LFUNC, RC = nargs*8
|
4138
|
+
| addu TMP1, BASE, RC
|
4139
|
+
| lw TMP2, L->maxstack
|
4140
|
+
| addu TMP0, RA, RC
|
4141
|
+
| sw LFUNC:RB, LO(TMP1) // Store copy of LFUNC.
|
4142
|
+
| addiu TMP3, RC, 8+FRAME_VARG
|
4143
|
+
| sltu AT, TMP0, TMP2
|
4144
|
+
| lw KBASE, -4+PC2PROTO(k)(PC)
|
4145
|
+
| beqz AT, ->vm_growstack_l
|
4146
|
+
|. sw TMP3, HI(TMP1) // Store delta + FRAME_VARG.
|
4147
|
+
| lbu TMP2, -4+PC2PROTO(numparams)(PC)
|
4148
|
+
| move RA, BASE
|
4149
|
+
| move RC, TMP1
|
4150
|
+
| ins_next1
|
4151
|
+
| beqz TMP2, >3
|
4152
|
+
|. addiu BASE, TMP1, 8
|
4153
|
+
|1:
|
4154
|
+
| lw TMP0, HI(RA)
|
4155
|
+
| lw TMP3, LO(RA)
|
4156
|
+
| sltu AT, RA, RC // Less args than parameters?
|
4157
|
+
| move CARG1, TMP0
|
4158
|
+
| movz TMP0, TISNIL, AT // Clear missing parameters.
|
4159
|
+
| movn CARG1, TISNIL, AT // Clear old fixarg slot (help the GC).
|
4160
|
+
| sw TMP3, 8+LO(TMP1)
|
4161
|
+
| addiu TMP2, TMP2, -1
|
4162
|
+
| sw TMP0, 8+HI(TMP1)
|
4163
|
+
| addiu TMP1, TMP1, 8
|
4164
|
+
| sw CARG1, HI(RA)
|
4165
|
+
| bnez TMP2, <1
|
4166
|
+
|. addiu RA, RA, 8
|
4167
|
+
|3:
|
4168
|
+
| ins_next2
|
4169
|
+
break;
|
4170
|
+
|
4171
|
+
case BC_FUNCC:
|
4172
|
+
case BC_FUNCCW:
|
4173
|
+
| // BASE = new base, RA = BASE+framesize*8, RB = CFUNC, RC = nargs*8
|
4174
|
+
if (op == BC_FUNCC) {
|
4175
|
+
| lw CFUNCADDR, CFUNC:RB->f
|
4176
|
+
} else {
|
4177
|
+
| lw CFUNCADDR, DISPATCH_GL(wrapf)(DISPATCH)
|
4178
|
+
}
|
4179
|
+
| addu TMP1, RA, NARGS8:RC
|
4180
|
+
| lw TMP2, L->maxstack
|
4181
|
+
| addu RC, BASE, NARGS8:RC
|
4182
|
+
| sw BASE, L->base
|
4183
|
+
| sltu AT, TMP2, TMP1
|
4184
|
+
| sw RC, L->top
|
4185
|
+
| li_vmstate C
|
4186
|
+
if (op == BC_FUNCCW) {
|
4187
|
+
| lw CARG2, CFUNC:RB->f
|
4188
|
+
}
|
4189
|
+
| bnez AT, ->vm_growstack_c // Need to grow stack.
|
4190
|
+
|. move CARG1, L
|
4191
|
+
| jalr CFUNCADDR // (lua_State *L [, lua_CFunction f])
|
4192
|
+
|. st_vmstate
|
4193
|
+
| // Returns nresults.
|
4194
|
+
| lw BASE, L->base
|
4195
|
+
| sll RD, CRET1, 3
|
4196
|
+
| lw TMP1, L->top
|
4197
|
+
| li_vmstate INTERP
|
4198
|
+
| lw PC, FRAME_PC(BASE) // Fetch PC of caller.
|
4199
|
+
| subu RA, TMP1, RD // RA = L->top - nresults*8
|
4200
|
+
| sw L, DISPATCH_GL(cur_L)(DISPATCH)
|
4201
|
+
| b ->vm_returnc
|
4202
|
+
|. st_vmstate
|
4203
|
+
break;
|
4204
|
+
|
4205
|
+
/* ---------------------------------------------------------------------- */
|
4206
|
+
|
4207
|
+
default:
|
4208
|
+
fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
|
4209
|
+
exit(2);
|
4210
|
+
break;
|
4211
|
+
}
|
4212
|
+
}
|
4213
|
+
|
4214
|
+
static int build_backend(BuildCtx *ctx)
|
4215
|
+
{
|
4216
|
+
int op;
|
4217
|
+
|
4218
|
+
dasm_growpc(Dst, BC__MAX);
|
4219
|
+
|
4220
|
+
build_subroutines(ctx);
|
4221
|
+
|
4222
|
+
|.code_op
|
4223
|
+
for (op = 0; op < BC__MAX; op++)
|
4224
|
+
build_ins(ctx, (BCOp)op, op);
|
4225
|
+
|
4226
|
+
return BC__MAX;
|
4227
|
+
}
|
4228
|
+
|
4229
|
+
/* Emit pseudo frame-info for all assembler functions. */
|
4230
|
+
static void emit_asm_debug(BuildCtx *ctx)
|
4231
|
+
{
|
4232
|
+
int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code);
|
4233
|
+
int i;
|
4234
|
+
switch (ctx->mode) {
|
4235
|
+
case BUILD_elfasm:
|
4236
|
+
fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n");
|
4237
|
+
fprintf(ctx->fp,
|
4238
|
+
".Lframe0:\n"
|
4239
|
+
"\t.4byte .LECIE0-.LSCIE0\n"
|
4240
|
+
".LSCIE0:\n"
|
4241
|
+
"\t.4byte 0xffffffff\n"
|
4242
|
+
"\t.byte 0x1\n"
|
4243
|
+
"\t.string \"\"\n"
|
4244
|
+
"\t.uleb128 0x1\n"
|
4245
|
+
"\t.sleb128 -4\n"
|
4246
|
+
"\t.byte 31\n"
|
4247
|
+
"\t.byte 0xc\n\t.uleb128 29\n\t.uleb128 0\n"
|
4248
|
+
"\t.align 2\n"
|
4249
|
+
".LECIE0:\n\n");
|
4250
|
+
fprintf(ctx->fp,
|
4251
|
+
".LSFDE0:\n"
|
4252
|
+
"\t.4byte .LEFDE0-.LASFDE0\n"
|
4253
|
+
".LASFDE0:\n"
|
4254
|
+
"\t.4byte .Lframe0\n"
|
4255
|
+
"\t.4byte .Lbegin\n"
|
4256
|
+
"\t.4byte %d\n"
|
4257
|
+
"\t.byte 0xe\n\t.uleb128 %d\n"
|
4258
|
+
"\t.byte 0x9f\n\t.sleb128 1\n"
|
4259
|
+
"\t.byte 0x9e\n\t.sleb128 2\n",
|
4260
|
+
fcofs, CFRAME_SIZE);
|
4261
|
+
for (i = 23; i >= 16; i--)
|
4262
|
+
fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+i, 26-i);
|
4263
|
+
for (i = 30; i >= 20; i -= 2)
|
4264
|
+
fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+32+i, 42-i);
|
4265
|
+
fprintf(ctx->fp,
|
4266
|
+
"\t.align 2\n"
|
4267
|
+
".LEFDE0:\n\n");
|
4268
|
+
#if LJ_HASFFI
|
4269
|
+
fprintf(ctx->fp,
|
4270
|
+
".LSFDE1:\n"
|
4271
|
+
"\t.4byte .LEFDE1-.LASFDE1\n"
|
4272
|
+
".LASFDE1:\n"
|
4273
|
+
"\t.4byte .Lframe0\n"
|
4274
|
+
"\t.4byte lj_vm_ffi_call\n"
|
4275
|
+
"\t.4byte %d\n"
|
4276
|
+
"\t.byte 0x9f\n\t.uleb128 1\n"
|
4277
|
+
"\t.byte 0x90\n\t.uleb128 2\n"
|
4278
|
+
"\t.byte 0xd\n\t.uleb128 0x10\n"
|
4279
|
+
"\t.align 2\n"
|
4280
|
+
".LEFDE1:\n\n", (int)ctx->codesz - fcofs);
|
4281
|
+
#endif
|
4282
|
+
fprintf(ctx->fp, "\t.section .eh_frame,\"aw\",@progbits\n");
|
4283
|
+
fprintf(ctx->fp,
|
4284
|
+
"\t.globl lj_err_unwind_dwarf\n"
|
4285
|
+
".Lframe1:\n"
|
4286
|
+
"\t.4byte .LECIE1-.LSCIE1\n"
|
4287
|
+
".LSCIE1:\n"
|
4288
|
+
"\t.4byte 0\n"
|
4289
|
+
"\t.byte 0x1\n"
|
4290
|
+
"\t.string \"zPR\"\n"
|
4291
|
+
"\t.uleb128 0x1\n"
|
4292
|
+
"\t.sleb128 -4\n"
|
4293
|
+
"\t.byte 31\n"
|
4294
|
+
"\t.uleb128 6\n" /* augmentation length */
|
4295
|
+
"\t.byte 0\n"
|
4296
|
+
"\t.4byte lj_err_unwind_dwarf\n"
|
4297
|
+
"\t.byte 0\n"
|
4298
|
+
"\t.byte 0xc\n\t.uleb128 29\n\t.uleb128 0\n"
|
4299
|
+
"\t.align 2\n"
|
4300
|
+
".LECIE1:\n\n");
|
4301
|
+
fprintf(ctx->fp,
|
4302
|
+
".LSFDE2:\n"
|
4303
|
+
"\t.4byte .LEFDE2-.LASFDE2\n"
|
4304
|
+
".LASFDE2:\n"
|
4305
|
+
"\t.4byte .LASFDE2-.Lframe1\n"
|
4306
|
+
"\t.4byte .Lbegin\n"
|
4307
|
+
"\t.4byte %d\n"
|
4308
|
+
"\t.uleb128 0\n" /* augmentation length */
|
4309
|
+
"\t.byte 0xe\n\t.uleb128 %d\n"
|
4310
|
+
"\t.byte 0x9f\n\t.sleb128 1\n"
|
4311
|
+
"\t.byte 0x9e\n\t.sleb128 2\n",
|
4312
|
+
fcofs, CFRAME_SIZE);
|
4313
|
+
for (i = 23; i >= 16; i--)
|
4314
|
+
fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+i, 26-i);
|
4315
|
+
for (i = 30; i >= 20; i -= 2)
|
4316
|
+
fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+32+i, 42-i);
|
4317
|
+
fprintf(ctx->fp,
|
4318
|
+
"\t.align 2\n"
|
4319
|
+
".LEFDE2:\n\n");
|
4320
|
+
#if LJ_HASFFI
|
4321
|
+
fprintf(ctx->fp,
|
4322
|
+
".Lframe2:\n"
|
4323
|
+
"\t.4byte .LECIE2-.LSCIE2\n"
|
4324
|
+
".LSCIE2:\n"
|
4325
|
+
"\t.4byte 0\n"
|
4326
|
+
"\t.byte 0x1\n"
|
4327
|
+
"\t.string \"zR\"\n"
|
4328
|
+
"\t.uleb128 0x1\n"
|
4329
|
+
"\t.sleb128 -4\n"
|
4330
|
+
"\t.byte 31\n"
|
4331
|
+
"\t.uleb128 1\n" /* augmentation length */
|
4332
|
+
"\t.byte 0\n"
|
4333
|
+
"\t.byte 0xc\n\t.uleb128 29\n\t.uleb128 0\n"
|
4334
|
+
"\t.align 2\n"
|
4335
|
+
".LECIE2:\n\n");
|
4336
|
+
fprintf(ctx->fp,
|
4337
|
+
".LSFDE3:\n"
|
4338
|
+
"\t.4byte .LEFDE3-.LASFDE3\n"
|
4339
|
+
".LASFDE3:\n"
|
4340
|
+
"\t.4byte .LASFDE3-.Lframe2\n"
|
4341
|
+
"\t.4byte lj_vm_ffi_call\n"
|
4342
|
+
"\t.4byte %d\n"
|
4343
|
+
"\t.uleb128 0\n" /* augmentation length */
|
4344
|
+
"\t.byte 0x9f\n\t.uleb128 1\n"
|
4345
|
+
"\t.byte 0x90\n\t.uleb128 2\n"
|
4346
|
+
"\t.byte 0xd\n\t.uleb128 0x10\n"
|
4347
|
+
"\t.align 2\n"
|
4348
|
+
".LEFDE3:\n\n", (int)ctx->codesz - fcofs);
|
4349
|
+
#endif
|
4350
|
+
break;
|
4351
|
+
default:
|
4352
|
+
break;
|
4353
|
+
}
|
4354
|
+
}
|
4355
|
+
|