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.
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