immunio 0.15.4 → 0.16.0

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