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,245 @@
1
+ /*
2
+ ** SINK: Allocation Sinking and Store Sinking.
3
+ ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
4
+ */
5
+
6
+ #define lj_opt_sink_c
7
+ #define LUA_CORE
8
+
9
+ #include "lj_obj.h"
10
+
11
+ #if LJ_HASJIT
12
+
13
+ #include "lj_ir.h"
14
+ #include "lj_jit.h"
15
+ #include "lj_iropt.h"
16
+ #include "lj_target.h"
17
+
18
+ /* Some local macros to save typing. Undef'd at the end. */
19
+ #define IR(ref) (&J->cur.ir[(ref)])
20
+
21
+ /* Check whether the store ref points to an eligible allocation. */
22
+ static IRIns *sink_checkalloc(jit_State *J, IRIns *irs)
23
+ {
24
+ IRIns *ir = IR(irs->op1);
25
+ if (!irref_isk(ir->op2))
26
+ return NULL; /* Non-constant key. */
27
+ if (ir->o == IR_HREFK || ir->o == IR_AREF)
28
+ ir = IR(ir->op1);
29
+ else if (!(ir->o == IR_HREF || ir->o == IR_NEWREF ||
30
+ ir->o == IR_FREF || ir->o == IR_ADD))
31
+ return NULL; /* Unhandled reference type (for XSTORE). */
32
+ ir = IR(ir->op1);
33
+ if (!(ir->o == IR_TNEW || ir->o == IR_TDUP || ir->o == IR_CNEW))
34
+ return NULL; /* Not an allocation. */
35
+ return ir; /* Return allocation. */
36
+ }
37
+
38
+ /* Recursively check whether a value depends on a PHI. */
39
+ static int sink_phidep(jit_State *J, IRRef ref)
40
+ {
41
+ IRIns *ir = IR(ref);
42
+ if (irt_isphi(ir->t)) return 1;
43
+ if (ir->op1 >= REF_FIRST && sink_phidep(J, ir->op1)) return 1;
44
+ if (ir->op2 >= REF_FIRST && sink_phidep(J, ir->op2)) return 1;
45
+ return 0;
46
+ }
47
+
48
+ /* Check whether a value is a sinkable PHI or loop-invariant. */
49
+ static int sink_checkphi(jit_State *J, IRIns *ira, IRRef ref)
50
+ {
51
+ if (ref >= REF_FIRST) {
52
+ IRIns *ir = IR(ref);
53
+ if (irt_isphi(ir->t) || (ir->o == IR_CONV && ir->op2 == IRCONV_NUM_INT &&
54
+ irt_isphi(IR(ir->op1)->t))) {
55
+ ira->prev++;
56
+ return 1; /* Sinkable PHI. */
57
+ }
58
+ /* Otherwise the value must be loop-invariant. */
59
+ return ref < J->loopref && !sink_phidep(J, ref);
60
+ }
61
+ return 1; /* Constant (non-PHI). */
62
+ }
63
+
64
+ /* Mark non-sinkable allocations using single-pass backward propagation.
65
+ **
66
+ ** Roots for the marking process are:
67
+ ** - Some PHIs or snapshots (see below).
68
+ ** - Non-PHI, non-constant values stored to PHI allocations.
69
+ ** - All guards.
70
+ ** - Any remaining loads not eliminated by store-to-load forwarding.
71
+ ** - Stores with non-constant keys.
72
+ ** - All stored values.
73
+ */
74
+ static void sink_mark_ins(jit_State *J)
75
+ {
76
+ IRIns *ir, *irlast = IR(J->cur.nins-1);
77
+ for (ir = irlast ; ; ir--) {
78
+ switch (ir->o) {
79
+ case IR_BASE:
80
+ return; /* Finished. */
81
+ case IR_CALLL: /* IRCALL_lj_tab_len */
82
+ case IR_ALOAD: case IR_HLOAD: case IR_XLOAD: case IR_TBAR:
83
+ irt_setmark(IR(ir->op1)->t); /* Mark ref for remaining loads. */
84
+ break;
85
+ case IR_FLOAD:
86
+ if (irt_ismarked(ir->t) || ir->op2 == IRFL_TAB_META)
87
+ irt_setmark(IR(ir->op1)->t); /* Mark table for remaining loads. */
88
+ break;
89
+ case IR_ASTORE: case IR_HSTORE: case IR_FSTORE: case IR_XSTORE: {
90
+ IRIns *ira = sink_checkalloc(J, ir);
91
+ if (!ira || (irt_isphi(ira->t) && !sink_checkphi(J, ira, ir->op2)))
92
+ irt_setmark(IR(ir->op1)->t); /* Mark ineligible ref. */
93
+ irt_setmark(IR(ir->op2)->t); /* Mark stored value. */
94
+ break;
95
+ }
96
+ #if LJ_HASFFI
97
+ case IR_CNEWI:
98
+ if (irt_isphi(ir->t) &&
99
+ (!sink_checkphi(J, ir, ir->op2) ||
100
+ (LJ_32 && ir+1 < irlast && (ir+1)->o == IR_HIOP &&
101
+ !sink_checkphi(J, ir, (ir+1)->op2))))
102
+ irt_setmark(ir->t); /* Mark ineligible allocation. */
103
+ /* fallthrough */
104
+ #endif
105
+ case IR_USTORE:
106
+ irt_setmark(IR(ir->op2)->t); /* Mark stored value. */
107
+ break;
108
+ #if LJ_HASFFI
109
+ case IR_CALLXS:
110
+ #endif
111
+ case IR_CALLS:
112
+ irt_setmark(IR(ir->op1)->t); /* Mark (potentially) stored values. */
113
+ break;
114
+ case IR_PHI: {
115
+ IRIns *irl = IR(ir->op1), *irr = IR(ir->op2);
116
+ irl->prev = irr->prev = 0; /* Clear PHI value counts. */
117
+ if (irl->o == irr->o &&
118
+ (irl->o == IR_TNEW || irl->o == IR_TDUP ||
119
+ (LJ_HASFFI && (irl->o == IR_CNEW || irl->o == IR_CNEWI))))
120
+ break;
121
+ irt_setmark(irl->t);
122
+ irt_setmark(irr->t);
123
+ break;
124
+ }
125
+ default:
126
+ if (irt_ismarked(ir->t) || irt_isguard(ir->t)) { /* Propagate mark. */
127
+ if (ir->op1 >= REF_FIRST) irt_setmark(IR(ir->op1)->t);
128
+ if (ir->op2 >= REF_FIRST) irt_setmark(IR(ir->op2)->t);
129
+ }
130
+ break;
131
+ }
132
+ }
133
+ }
134
+
135
+ /* Mark all instructions referenced by a snapshot. */
136
+ static void sink_mark_snap(jit_State *J, SnapShot *snap)
137
+ {
138
+ SnapEntry *map = &J->cur.snapmap[snap->mapofs];
139
+ MSize n, nent = snap->nent;
140
+ for (n = 0; n < nent; n++) {
141
+ IRRef ref = snap_ref(map[n]);
142
+ if (!irref_isk(ref))
143
+ irt_setmark(IR(ref)->t);
144
+ }
145
+ }
146
+
147
+ /* Iteratively remark PHI refs with differing marks or PHI value counts. */
148
+ static void sink_remark_phi(jit_State *J)
149
+ {
150
+ IRIns *ir;
151
+ int remark;
152
+ do {
153
+ remark = 0;
154
+ for (ir = IR(J->cur.nins-1); ir->o == IR_PHI; ir--) {
155
+ IRIns *irl = IR(ir->op1), *irr = IR(ir->op2);
156
+ if (((irl->t.irt ^ irr->t.irt) & IRT_MARK))
157
+ remark = 1;
158
+ else if (irl->prev == irr->prev)
159
+ continue;
160
+ irt_setmark(IR(ir->op1)->t);
161
+ irt_setmark(IR(ir->op2)->t);
162
+ }
163
+ } while (remark);
164
+ }
165
+
166
+ /* Sweep instructions and tag sunken allocations and stores. */
167
+ static void sink_sweep_ins(jit_State *J)
168
+ {
169
+ IRIns *ir, *irfirst = IR(J->cur.nk);
170
+ for (ir = IR(J->cur.nins-1) ; ir >= irfirst; ir--) {
171
+ switch (ir->o) {
172
+ case IR_ASTORE: case IR_HSTORE: case IR_FSTORE: case IR_XSTORE: {
173
+ IRIns *ira = sink_checkalloc(J, ir);
174
+ if (ira && !irt_ismarked(ira->t)) {
175
+ int delta = (int)(ir - ira);
176
+ ir->prev = REGSP(RID_SINK, delta > 255 ? 255 : delta);
177
+ } else {
178
+ ir->prev = REGSP_INIT;
179
+ }
180
+ break;
181
+ }
182
+ case IR_NEWREF:
183
+ if (!irt_ismarked(IR(ir->op1)->t)) {
184
+ ir->prev = REGSP(RID_SINK, 0);
185
+ } else {
186
+ irt_clearmark(ir->t);
187
+ ir->prev = REGSP_INIT;
188
+ }
189
+ break;
190
+ #if LJ_HASFFI
191
+ case IR_CNEW: case IR_CNEWI:
192
+ #endif
193
+ case IR_TNEW: case IR_TDUP:
194
+ if (!irt_ismarked(ir->t)) {
195
+ ir->t.irt &= ~IRT_GUARD;
196
+ ir->prev = REGSP(RID_SINK, 0);
197
+ J->cur.sinktags = 1; /* Signal present SINK tags to assembler. */
198
+ } else {
199
+ irt_clearmark(ir->t);
200
+ ir->prev = REGSP_INIT;
201
+ }
202
+ break;
203
+ case IR_PHI: {
204
+ IRIns *ira = IR(ir->op2);
205
+ if (!irt_ismarked(ira->t) &&
206
+ (ira->o == IR_TNEW || ira->o == IR_TDUP ||
207
+ (LJ_HASFFI && (ira->o == IR_CNEW || ira->o == IR_CNEWI)))) {
208
+ ir->prev = REGSP(RID_SINK, 0);
209
+ } else {
210
+ ir->prev = REGSP_INIT;
211
+ }
212
+ break;
213
+ }
214
+ default:
215
+ irt_clearmark(ir->t);
216
+ ir->prev = REGSP_INIT;
217
+ break;
218
+ }
219
+ }
220
+ }
221
+
222
+ /* Allocation sinking and store sinking.
223
+ **
224
+ ** 1. Mark all non-sinkable allocations.
225
+ ** 2. Then sink all remaining allocations and the related stores.
226
+ */
227
+ void lj_opt_sink(jit_State *J)
228
+ {
229
+ const uint32_t need = (JIT_F_OPT_SINK|JIT_F_OPT_FWD|
230
+ JIT_F_OPT_DCE|JIT_F_OPT_CSE|JIT_F_OPT_FOLD);
231
+ if ((J->flags & need) == need &&
232
+ (J->chain[IR_TNEW] || J->chain[IR_TDUP] ||
233
+ (LJ_HASFFI && (J->chain[IR_CNEW] || J->chain[IR_CNEWI])))) {
234
+ if (!J->loopref)
235
+ sink_mark_snap(J, &J->cur.snap[J->cur.nsnap-1]);
236
+ sink_mark_ins(J);
237
+ if (J->loopref)
238
+ sink_remark_phi(J);
239
+ sink_sweep_ins(J);
240
+ }
241
+ }
242
+
243
+ #undef IR
244
+
245
+ #endif
@@ -0,0 +1,856 @@
1
+ /*
2
+ ** SPLIT: Split 64 bit IR instructions into 32 bit IR instructions.
3
+ ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
4
+ */
5
+
6
+ #define lj_opt_split_c
7
+ #define LUA_CORE
8
+
9
+ #include "lj_obj.h"
10
+
11
+ #if LJ_HASJIT && (LJ_SOFTFP || (LJ_32 && LJ_HASFFI))
12
+
13
+ #include "lj_err.h"
14
+ #include "lj_buf.h"
15
+ #include "lj_ir.h"
16
+ #include "lj_jit.h"
17
+ #include "lj_ircall.h"
18
+ #include "lj_iropt.h"
19
+ #include "lj_vm.h"
20
+
21
+ /* SPLIT pass:
22
+ **
23
+ ** This pass splits up 64 bit IR instructions into multiple 32 bit IR
24
+ ** instructions. It's only active for soft-float targets or for 32 bit CPUs
25
+ ** which lack native 64 bit integer operations (the FFI is currently the
26
+ ** only emitter for 64 bit integer instructions).
27
+ **
28
+ ** Splitting the IR in a separate pass keeps each 32 bit IR assembler
29
+ ** backend simple. Only a small amount of extra functionality needs to be
30
+ ** implemented. This is much easier than adding support for allocating
31
+ ** register pairs to each backend (believe me, I tried). A few simple, but
32
+ ** important optimizations can be performed by the SPLIT pass, which would
33
+ ** be tedious to do in the backend.
34
+ **
35
+ ** The basic idea is to replace each 64 bit IR instruction with its 32 bit
36
+ ** equivalent plus an extra HIOP instruction. The splitted IR is not passed
37
+ ** through FOLD or any other optimizations, so each HIOP is guaranteed to
38
+ ** immediately follow it's counterpart. The actual functionality of HIOP is
39
+ ** inferred from the previous instruction.
40
+ **
41
+ ** The operands of HIOP hold the hiword input references. The output of HIOP
42
+ ** is the hiword output reference, which is also used to hold the hiword
43
+ ** register or spill slot information. The register allocator treats this
44
+ ** instruction independently of any other instruction, which improves code
45
+ ** quality compared to using fixed register pairs.
46
+ **
47
+ ** It's easier to split up some instructions into two regular 32 bit
48
+ ** instructions. E.g. XLOAD is split up into two XLOADs with two different
49
+ ** addresses. Obviously 64 bit constants need to be split up into two 32 bit
50
+ ** constants, too. Some hiword instructions can be entirely omitted, e.g.
51
+ ** when zero-extending a 32 bit value to 64 bits. 64 bit arguments for calls
52
+ ** are split up into two 32 bit arguments each.
53
+ **
54
+ ** On soft-float targets, floating-point instructions are directly converted
55
+ ** to soft-float calls by the SPLIT pass (except for comparisons and MIN/MAX).
56
+ ** HIOP for number results has the type IRT_SOFTFP ("sfp" in -jdump).
57
+ **
58
+ ** Here's the IR and x64 machine code for 'x.b = x.a + 1' for a struct with
59
+ ** two int64_t fields:
60
+ **
61
+ ** 0100 p32 ADD base +8
62
+ ** 0101 i64 XLOAD 0100
63
+ ** 0102 i64 ADD 0101 +1
64
+ ** 0103 p32 ADD base +16
65
+ ** 0104 i64 XSTORE 0103 0102
66
+ **
67
+ ** mov rax, [esi+0x8]
68
+ ** add rax, +0x01
69
+ ** mov [esi+0x10], rax
70
+ **
71
+ ** Here's the transformed IR and the x86 machine code after the SPLIT pass:
72
+ **
73
+ ** 0100 p32 ADD base +8
74
+ ** 0101 int XLOAD 0100
75
+ ** 0102 p32 ADD base +12
76
+ ** 0103 int XLOAD 0102
77
+ ** 0104 int ADD 0101 +1
78
+ ** 0105 int HIOP 0103 +0
79
+ ** 0106 p32 ADD base +16
80
+ ** 0107 int XSTORE 0106 0104
81
+ ** 0108 int HIOP 0106 0105
82
+ **
83
+ ** mov eax, [esi+0x8]
84
+ ** mov ecx, [esi+0xc]
85
+ ** add eax, +0x01
86
+ ** adc ecx, +0x00
87
+ ** mov [esi+0x10], eax
88
+ ** mov [esi+0x14], ecx
89
+ **
90
+ ** You may notice the reassociated hiword address computation, which is
91
+ ** later fused into the mov operands by the assembler.
92
+ */
93
+
94
+ /* Some local macros to save typing. Undef'd at the end. */
95
+ #define IR(ref) (&J->cur.ir[(ref)])
96
+
97
+ /* Directly emit the transformed IR without updating chains etc. */
98
+ static IRRef split_emit(jit_State *J, uint16_t ot, IRRef1 op1, IRRef1 op2)
99
+ {
100
+ IRRef nref = lj_ir_nextins(J);
101
+ IRIns *ir = IR(nref);
102
+ ir->ot = ot;
103
+ ir->op1 = op1;
104
+ ir->op2 = op2;
105
+ return nref;
106
+ }
107
+
108
+ #if LJ_SOFTFP
109
+ /* Emit a (checked) number to integer conversion. */
110
+ static IRRef split_num2int(jit_State *J, IRRef lo, IRRef hi, int check)
111
+ {
112
+ IRRef tmp, res;
113
+ #if LJ_LE
114
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), lo, hi);
115
+ #else
116
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hi, lo);
117
+ #endif
118
+ res = split_emit(J, IRTI(IR_CALLN), tmp, IRCALL_softfp_d2i);
119
+ if (check) {
120
+ tmp = split_emit(J, IRTI(IR_CALLN), res, IRCALL_softfp_i2d);
121
+ split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), tmp, tmp);
122
+ split_emit(J, IRTGI(IR_EQ), tmp, lo);
123
+ split_emit(J, IRTG(IR_HIOP, IRT_SOFTFP), tmp+1, hi);
124
+ }
125
+ return res;
126
+ }
127
+
128
+ /* Emit a CALLN with one split 64 bit argument. */
129
+ static IRRef split_call_l(jit_State *J, IRRef1 *hisubst, IRIns *oir,
130
+ IRIns *ir, IRCallID id)
131
+ {
132
+ IRRef tmp, op1 = ir->op1;
133
+ J->cur.nins--;
134
+ #if LJ_LE
135
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), oir[op1].prev, hisubst[op1]);
136
+ #else
137
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev);
138
+ #endif
139
+ ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, id);
140
+ return split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), tmp, tmp);
141
+ }
142
+ #endif
143
+
144
+ /* Emit a CALLN with one split 64 bit argument and a 32 bit argument. */
145
+ static IRRef split_call_li(jit_State *J, IRRef1 *hisubst, IRIns *oir,
146
+ IRIns *ir, IRCallID id)
147
+ {
148
+ IRRef tmp, op1 = ir->op1, op2 = ir->op2;
149
+ J->cur.nins--;
150
+ #if LJ_LE
151
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), oir[op1].prev, hisubst[op1]);
152
+ #else
153
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev);
154
+ #endif
155
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, oir[op2].prev);
156
+ ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, id);
157
+ return split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), tmp, tmp);
158
+ }
159
+
160
+ /* Emit a CALLN with two split 64 bit arguments. */
161
+ static IRRef split_call_ll(jit_State *J, IRRef1 *hisubst, IRIns *oir,
162
+ IRIns *ir, IRCallID id)
163
+ {
164
+ IRRef tmp, op1 = ir->op1, op2 = ir->op2;
165
+ J->cur.nins--;
166
+ #if LJ_LE
167
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), oir[op1].prev, hisubst[op1]);
168
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, oir[op2].prev);
169
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, hisubst[op2]);
170
+ #else
171
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev);
172
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, hisubst[op2]);
173
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, oir[op2].prev);
174
+ #endif
175
+ ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, id);
176
+ return split_emit(J,
177
+ IRT(IR_HIOP, (LJ_SOFTFP && irt_isnum(ir->t)) ? IRT_SOFTFP : IRT_INT),
178
+ tmp, tmp);
179
+ }
180
+
181
+ /* Get a pointer to the other 32 bit word (LE: hiword, BE: loword). */
182
+ static IRRef split_ptr(jit_State *J, IRIns *oir, IRRef ref)
183
+ {
184
+ IRRef nref = oir[ref].prev;
185
+ IRIns *ir = IR(nref);
186
+ int32_t ofs = 4;
187
+ if (ir->o == IR_KPTR)
188
+ return lj_ir_kptr(J, (char *)ir_kptr(ir) + ofs);
189
+ if (ir->o == IR_ADD && irref_isk(ir->op2) && !irt_isphi(oir[ref].t)) {
190
+ /* Reassociate address. */
191
+ ofs += IR(ir->op2)->i;
192
+ nref = ir->op1;
193
+ if (ofs == 0) return nref;
194
+ }
195
+ return split_emit(J, IRTI(IR_ADD), nref, lj_ir_kint(J, ofs));
196
+ }
197
+
198
+ #if LJ_HASFFI
199
+ static IRRef split_bitshift(jit_State *J, IRRef1 *hisubst,
200
+ IRIns *oir, IRIns *nir, IRIns *ir)
201
+ {
202
+ IROp op = ir->o;
203
+ IRRef kref = nir->op2;
204
+ if (irref_isk(kref)) { /* Optimize constant shifts. */
205
+ int32_t k = (IR(kref)->i & 63);
206
+ IRRef lo = nir->op1, hi = hisubst[ir->op1];
207
+ if (op == IR_BROL || op == IR_BROR) {
208
+ if (op == IR_BROR) k = (-k & 63);
209
+ if (k >= 32) { IRRef t = lo; lo = hi; hi = t; k -= 32; }
210
+ if (k == 0) {
211
+ passthrough:
212
+ J->cur.nins--;
213
+ ir->prev = lo;
214
+ return hi;
215
+ } else {
216
+ TRef k1, k2;
217
+ IRRef t1, t2, t3, t4;
218
+ J->cur.nins--;
219
+ k1 = lj_ir_kint(J, k);
220
+ k2 = lj_ir_kint(J, (-k & 31));
221
+ t1 = split_emit(J, IRTI(IR_BSHL), lo, k1);
222
+ t2 = split_emit(J, IRTI(IR_BSHL), hi, k1);
223
+ t3 = split_emit(J, IRTI(IR_BSHR), lo, k2);
224
+ t4 = split_emit(J, IRTI(IR_BSHR), hi, k2);
225
+ ir->prev = split_emit(J, IRTI(IR_BOR), t1, t4);
226
+ return split_emit(J, IRTI(IR_BOR), t2, t3);
227
+ }
228
+ } else if (k == 0) {
229
+ goto passthrough;
230
+ } else if (k < 32) {
231
+ if (op == IR_BSHL) {
232
+ IRRef t1 = split_emit(J, IRTI(IR_BSHL), hi, kref);
233
+ IRRef t2 = split_emit(J, IRTI(IR_BSHR), lo, lj_ir_kint(J, (-k&31)));
234
+ return split_emit(J, IRTI(IR_BOR), t1, t2);
235
+ } else {
236
+ IRRef t1 = ir->prev, t2;
237
+ lua_assert(op == IR_BSHR || op == IR_BSAR);
238
+ nir->o = IR_BSHR;
239
+ t2 = split_emit(J, IRTI(IR_BSHL), hi, lj_ir_kint(J, (-k&31)));
240
+ ir->prev = split_emit(J, IRTI(IR_BOR), t1, t2);
241
+ return split_emit(J, IRTI(op), hi, kref);
242
+ }
243
+ } else {
244
+ if (op == IR_BSHL) {
245
+ if (k == 32)
246
+ J->cur.nins--;
247
+ else
248
+ lo = ir->prev;
249
+ ir->prev = lj_ir_kint(J, 0);
250
+ return lo;
251
+ } else {
252
+ lua_assert(op == IR_BSHR || op == IR_BSAR);
253
+ if (k == 32) {
254
+ J->cur.nins--;
255
+ ir->prev = hi;
256
+ } else {
257
+ nir->op1 = hi;
258
+ }
259
+ if (op == IR_BSHR)
260
+ return lj_ir_kint(J, 0);
261
+ else
262
+ return split_emit(J, IRTI(IR_BSAR), hi, lj_ir_kint(J, 31));
263
+ }
264
+ }
265
+ }
266
+ return split_call_li(J, hisubst, oir, ir,
267
+ op - IR_BSHL + IRCALL_lj_carith_shl64);
268
+ }
269
+
270
+ static IRRef split_bitop(jit_State *J, IRRef1 *hisubst,
271
+ IRIns *nir, IRIns *ir)
272
+ {
273
+ IROp op = ir->o;
274
+ IRRef hi, kref = nir->op2;
275
+ if (irref_isk(kref)) { /* Optimize bit operations with lo constant. */
276
+ int32_t k = IR(kref)->i;
277
+ if (k == 0 || k == -1) {
278
+ if (op == IR_BAND) k = ~k;
279
+ if (k == 0) {
280
+ J->cur.nins--;
281
+ ir->prev = nir->op1;
282
+ } else if (op == IR_BXOR) {
283
+ nir->o = IR_BNOT;
284
+ nir->op2 = 0;
285
+ } else {
286
+ J->cur.nins--;
287
+ ir->prev = kref;
288
+ }
289
+ }
290
+ }
291
+ hi = hisubst[ir->op1];
292
+ kref = hisubst[ir->op2];
293
+ if (irref_isk(kref)) { /* Optimize bit operations with hi constant. */
294
+ int32_t k = IR(kref)->i;
295
+ if (k == 0 || k == -1) {
296
+ if (op == IR_BAND) k = ~k;
297
+ if (k == 0) {
298
+ return hi;
299
+ } else if (op == IR_BXOR) {
300
+ return split_emit(J, IRTI(IR_BNOT), hi, 0);
301
+ } else {
302
+ return kref;
303
+ }
304
+ }
305
+ }
306
+ return split_emit(J, IRTI(op), hi, kref);
307
+ }
308
+ #endif
309
+
310
+ /* Substitute references of a snapshot. */
311
+ static void split_subst_snap(jit_State *J, SnapShot *snap, IRIns *oir)
312
+ {
313
+ SnapEntry *map = &J->cur.snapmap[snap->mapofs];
314
+ MSize n, nent = snap->nent;
315
+ for (n = 0; n < nent; n++) {
316
+ SnapEntry sn = map[n];
317
+ IRIns *ir = &oir[snap_ref(sn)];
318
+ if (!(LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && irref_isk(snap_ref(sn))))
319
+ map[n] = ((sn & 0xffff0000) | ir->prev);
320
+ }
321
+ }
322
+
323
+ /* Transform the old IR to the new IR. */
324
+ static void split_ir(jit_State *J)
325
+ {
326
+ IRRef nins = J->cur.nins, nk = J->cur.nk;
327
+ MSize irlen = nins - nk;
328
+ MSize need = (irlen+1)*(sizeof(IRIns) + sizeof(IRRef1));
329
+ IRIns *oir = (IRIns *)lj_buf_tmp(J->L, need);
330
+ IRRef1 *hisubst;
331
+ IRRef ref, snref;
332
+ SnapShot *snap;
333
+
334
+ /* Copy old IR to buffer. */
335
+ memcpy(oir, IR(nk), irlen*sizeof(IRIns));
336
+ /* Bias hiword substitution table and old IR. Loword kept in field prev. */
337
+ hisubst = (IRRef1 *)&oir[irlen] - nk;
338
+ oir -= nk;
339
+
340
+ /* Remove all IR instructions, but retain IR constants. */
341
+ J->cur.nins = REF_FIRST;
342
+ J->loopref = 0;
343
+
344
+ /* Process constants and fixed references. */
345
+ for (ref = nk; ref <= REF_BASE; ref++) {
346
+ IRIns *ir = &oir[ref];
347
+ if ((LJ_SOFTFP && ir->o == IR_KNUM) || ir->o == IR_KINT64) {
348
+ /* Split up 64 bit constant. */
349
+ TValue tv = *ir_k64(ir);
350
+ ir->prev = lj_ir_kint(J, (int32_t)tv.u32.lo);
351
+ hisubst[ref] = lj_ir_kint(J, (int32_t)tv.u32.hi);
352
+ } else {
353
+ ir->prev = ref; /* Identity substitution for loword. */
354
+ hisubst[ref] = 0;
355
+ }
356
+ }
357
+
358
+ /* Process old IR instructions. */
359
+ snap = J->cur.snap;
360
+ snref = snap->ref;
361
+ for (ref = REF_FIRST; ref < nins; ref++) {
362
+ IRIns *ir = &oir[ref];
363
+ IRRef nref = lj_ir_nextins(J);
364
+ IRIns *nir = IR(nref);
365
+ IRRef hi = 0;
366
+
367
+ if (ref >= snref) {
368
+ snap->ref = nref;
369
+ split_subst_snap(J, snap++, oir);
370
+ snref = snap < &J->cur.snap[J->cur.nsnap] ? snap->ref : ~(IRRef)0;
371
+ }
372
+
373
+ /* Copy-substitute old instruction to new instruction. */
374
+ nir->op1 = ir->op1 < nk ? ir->op1 : oir[ir->op1].prev;
375
+ nir->op2 = ir->op2 < nk ? ir->op2 : oir[ir->op2].prev;
376
+ ir->prev = nref; /* Loword substitution. */
377
+ nir->o = ir->o;
378
+ nir->t.irt = ir->t.irt & ~(IRT_MARK|IRT_ISPHI);
379
+ hisubst[ref] = 0;
380
+
381
+ /* Split 64 bit instructions. */
382
+ #if LJ_SOFTFP
383
+ if (irt_isnum(ir->t)) {
384
+ nir->t.irt = IRT_INT | (nir->t.irt & IRT_GUARD); /* Turn into INT op. */
385
+ /* Note: hi ref = lo ref + 1! Required for SNAP_SOFTFPNUM logic. */
386
+ switch (ir->o) {
387
+ case IR_ADD:
388
+ hi = split_call_ll(J, hisubst, oir, ir, IRCALL_softfp_add);
389
+ break;
390
+ case IR_SUB:
391
+ hi = split_call_ll(J, hisubst, oir, ir, IRCALL_softfp_sub);
392
+ break;
393
+ case IR_MUL:
394
+ hi = split_call_ll(J, hisubst, oir, ir, IRCALL_softfp_mul);
395
+ break;
396
+ case IR_DIV:
397
+ hi = split_call_ll(J, hisubst, oir, ir, IRCALL_softfp_div);
398
+ break;
399
+ case IR_POW:
400
+ hi = split_call_li(J, hisubst, oir, ir, IRCALL_lj_vm_powi);
401
+ break;
402
+ case IR_FPMATH:
403
+ /* Try to rejoin pow from EXP2, MUL and LOG2. */
404
+ if (nir->op2 == IRFPM_EXP2 && nir->op1 > J->loopref) {
405
+ IRIns *irp = IR(nir->op1);
406
+ if (irp->o == IR_CALLN && irp->op2 == IRCALL_softfp_mul) {
407
+ IRIns *irm4 = IR(irp->op1);
408
+ IRIns *irm3 = IR(irm4->op1);
409
+ IRIns *irm12 = IR(irm3->op1);
410
+ IRIns *irl1 = IR(irm12->op1);
411
+ if (irm12->op1 > J->loopref && irl1->o == IR_CALLN &&
412
+ irl1->op2 == IRCALL_lj_vm_log2) {
413
+ IRRef tmp = irl1->op1; /* Recycle first two args from LOG2. */
414
+ IRRef arg3 = irm3->op2, arg4 = irm4->op2;
415
+ J->cur.nins--;
416
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, arg3);
417
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, arg4);
418
+ ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, IRCALL_pow);
419
+ hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), tmp, tmp);
420
+ break;
421
+ }
422
+ }
423
+ }
424
+ hi = split_call_l(J, hisubst, oir, ir, IRCALL_lj_vm_floor + ir->op2);
425
+ break;
426
+ case IR_ATAN2:
427
+ hi = split_call_ll(J, hisubst, oir, ir, IRCALL_atan2);
428
+ break;
429
+ case IR_LDEXP:
430
+ hi = split_call_li(J, hisubst, oir, ir, IRCALL_ldexp);
431
+ break;
432
+ case IR_NEG: case IR_ABS:
433
+ nir->o = IR_CONV; /* Pass through loword. */
434
+ nir->op2 = (IRT_INT << 5) | IRT_INT;
435
+ hi = split_emit(J, IRT(ir->o == IR_NEG ? IR_BXOR : IR_BAND, IRT_SOFTFP),
436
+ hisubst[ir->op1], hisubst[ir->op2]);
437
+ break;
438
+ case IR_SLOAD:
439
+ if ((nir->op2 & IRSLOAD_CONVERT)) { /* Convert from int to number. */
440
+ nir->op2 &= ~IRSLOAD_CONVERT;
441
+ ir->prev = nref = split_emit(J, IRTI(IR_CALLN), nref,
442
+ IRCALL_softfp_i2d);
443
+ hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref);
444
+ break;
445
+ }
446
+ /* fallthrough */
447
+ case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
448
+ case IR_STRTO:
449
+ hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref);
450
+ break;
451
+ case IR_XLOAD: {
452
+ IRIns inslo = *nir; /* Save/undo the emit of the lo XLOAD. */
453
+ J->cur.nins--;
454
+ hi = split_ptr(J, oir, ir->op1); /* Insert the hiref ADD. */
455
+ nref = lj_ir_nextins(J);
456
+ nir = IR(nref);
457
+ *nir = inslo; /* Re-emit lo XLOAD immediately before hi XLOAD. */
458
+ hi = split_emit(J, IRT(IR_XLOAD, IRT_SOFTFP), hi, ir->op2);
459
+ #if LJ_LE
460
+ ir->prev = nref;
461
+ #else
462
+ ir->prev = hi; hi = nref;
463
+ #endif
464
+ break;
465
+ }
466
+ case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_XSTORE:
467
+ split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nir->op1, hisubst[ir->op2]);
468
+ break;
469
+ case IR_CONV: { /* Conversion to number. Others handled below. */
470
+ IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
471
+ UNUSED(st);
472
+ #if LJ_32 && LJ_HASFFI
473
+ if (st == IRT_I64 || st == IRT_U64) {
474
+ hi = split_call_l(J, hisubst, oir, ir,
475
+ st == IRT_I64 ? IRCALL_fp64_l2d : IRCALL_fp64_ul2d);
476
+ break;
477
+ }
478
+ #endif
479
+ lua_assert(st == IRT_INT ||
480
+ (LJ_32 && LJ_HASFFI && (st == IRT_U32 || st == IRT_FLOAT)));
481
+ nir->o = IR_CALLN;
482
+ #if LJ_32 && LJ_HASFFI
483
+ nir->op2 = st == IRT_INT ? IRCALL_softfp_i2d :
484
+ st == IRT_FLOAT ? IRCALL_softfp_f2d :
485
+ IRCALL_softfp_ui2d;
486
+ #else
487
+ nir->op2 = IRCALL_softfp_i2d;
488
+ #endif
489
+ hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref);
490
+ break;
491
+ }
492
+ case IR_CALLN:
493
+ case IR_CALLL:
494
+ case IR_CALLS:
495
+ case IR_CALLXS:
496
+ goto split_call;
497
+ case IR_PHI:
498
+ if (nir->op1 == nir->op2)
499
+ J->cur.nins--; /* Drop useless PHIs. */
500
+ if (hisubst[ir->op1] != hisubst[ir->op2])
501
+ split_emit(J, IRT(IR_PHI, IRT_SOFTFP),
502
+ hisubst[ir->op1], hisubst[ir->op2]);
503
+ break;
504
+ case IR_HIOP:
505
+ J->cur.nins--; /* Drop joining HIOP. */
506
+ ir->prev = nir->op1;
507
+ hi = nir->op2;
508
+ break;
509
+ default:
510
+ lua_assert(ir->o <= IR_NE || ir->o == IR_MIN || ir->o == IR_MAX);
511
+ hi = split_emit(J, IRTG(IR_HIOP, IRT_SOFTFP),
512
+ hisubst[ir->op1], hisubst[ir->op2]);
513
+ break;
514
+ }
515
+ } else
516
+ #endif
517
+ #if LJ_32 && LJ_HASFFI
518
+ if (irt_isint64(ir->t)) {
519
+ IRRef hiref = hisubst[ir->op1];
520
+ nir->t.irt = IRT_INT | (nir->t.irt & IRT_GUARD); /* Turn into INT op. */
521
+ switch (ir->o) {
522
+ case IR_ADD:
523
+ case IR_SUB:
524
+ /* Use plain op for hiword if loword cannot produce a carry/borrow. */
525
+ if (irref_isk(nir->op2) && IR(nir->op2)->i == 0) {
526
+ ir->prev = nir->op1; /* Pass through loword. */
527
+ nir->op1 = hiref; nir->op2 = hisubst[ir->op2];
528
+ hi = nref;
529
+ break;
530
+ }
531
+ /* fallthrough */
532
+ case IR_NEG:
533
+ hi = split_emit(J, IRTI(IR_HIOP), hiref, hisubst[ir->op2]);
534
+ break;
535
+ case IR_MUL:
536
+ hi = split_call_ll(J, hisubst, oir, ir, IRCALL_lj_carith_mul64);
537
+ break;
538
+ case IR_DIV:
539
+ hi = split_call_ll(J, hisubst, oir, ir,
540
+ irt_isi64(ir->t) ? IRCALL_lj_carith_divi64 :
541
+ IRCALL_lj_carith_divu64);
542
+ break;
543
+ case IR_MOD:
544
+ hi = split_call_ll(J, hisubst, oir, ir,
545
+ irt_isi64(ir->t) ? IRCALL_lj_carith_modi64 :
546
+ IRCALL_lj_carith_modu64);
547
+ break;
548
+ case IR_POW:
549
+ hi = split_call_ll(J, hisubst, oir, ir,
550
+ irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 :
551
+ IRCALL_lj_carith_powu64);
552
+ break;
553
+ case IR_BNOT:
554
+ hi = split_emit(J, IRTI(IR_BNOT), hiref, 0);
555
+ break;
556
+ case IR_BSWAP:
557
+ ir->prev = split_emit(J, IRTI(IR_BSWAP), hiref, 0);
558
+ hi = nref;
559
+ break;
560
+ case IR_BAND: case IR_BOR: case IR_BXOR:
561
+ hi = split_bitop(J, hisubst, nir, ir);
562
+ break;
563
+ case IR_BSHL: case IR_BSHR: case IR_BSAR: case IR_BROL: case IR_BROR:
564
+ hi = split_bitshift(J, hisubst, oir, nir, ir);
565
+ break;
566
+ case IR_FLOAD:
567
+ lua_assert(ir->op2 == IRFL_CDATA_INT64);
568
+ hi = split_emit(J, IRTI(IR_FLOAD), nir->op1, IRFL_CDATA_INT64_4);
569
+ #if LJ_BE
570
+ ir->prev = hi; hi = nref;
571
+ #endif
572
+ break;
573
+ case IR_XLOAD:
574
+ hi = split_emit(J, IRTI(IR_XLOAD), split_ptr(J, oir, ir->op1), ir->op2);
575
+ #if LJ_BE
576
+ ir->prev = hi; hi = nref;
577
+ #endif
578
+ break;
579
+ case IR_XSTORE:
580
+ split_emit(J, IRTI(IR_HIOP), nir->op1, hisubst[ir->op2]);
581
+ break;
582
+ case IR_CONV: { /* Conversion to 64 bit integer. Others handled below. */
583
+ IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
584
+ #if LJ_SOFTFP
585
+ if (st == IRT_NUM) { /* NUM to 64 bit int conv. */
586
+ hi = split_call_l(J, hisubst, oir, ir,
587
+ irt_isi64(ir->t) ? IRCALL_fp64_d2l : IRCALL_fp64_d2ul);
588
+ } else if (st == IRT_FLOAT) { /* FLOAT to 64 bit int conv. */
589
+ nir->o = IR_CALLN;
590
+ nir->op2 = irt_isi64(ir->t) ? IRCALL_fp64_f2l : IRCALL_fp64_f2ul;
591
+ hi = split_emit(J, IRTI(IR_HIOP), nref, nref);
592
+ }
593
+ #else
594
+ if (st == IRT_NUM || st == IRT_FLOAT) { /* FP to 64 bit int conv. */
595
+ hi = split_emit(J, IRTI(IR_HIOP), nir->op1, nref);
596
+ }
597
+ #endif
598
+ else if (st == IRT_I64 || st == IRT_U64) { /* 64/64 bit cast. */
599
+ /* Drop cast, since assembler doesn't care. */
600
+ goto fwdlo;
601
+ } else if ((ir->op2 & IRCONV_SEXT)) { /* Sign-extend to 64 bit. */
602
+ IRRef k31 = lj_ir_kint(J, 31);
603
+ nir = IR(nref); /* May have been reallocated. */
604
+ ir->prev = nir->op1; /* Pass through loword. */
605
+ nir->o = IR_BSAR; /* hi = bsar(lo, 31). */
606
+ nir->op2 = k31;
607
+ hi = nref;
608
+ } else { /* Zero-extend to 64 bit. */
609
+ hi = lj_ir_kint(J, 0);
610
+ goto fwdlo;
611
+ }
612
+ break;
613
+ }
614
+ case IR_CALLXS:
615
+ goto split_call;
616
+ case IR_PHI: {
617
+ IRRef hiref2;
618
+ if ((irref_isk(nir->op1) && irref_isk(nir->op2)) ||
619
+ nir->op1 == nir->op2)
620
+ J->cur.nins--; /* Drop useless PHIs. */
621
+ hiref2 = hisubst[ir->op2];
622
+ if (!((irref_isk(hiref) && irref_isk(hiref2)) || hiref == hiref2))
623
+ split_emit(J, IRTI(IR_PHI), hiref, hiref2);
624
+ break;
625
+ }
626
+ case IR_HIOP:
627
+ J->cur.nins--; /* Drop joining HIOP. */
628
+ ir->prev = nir->op1;
629
+ hi = nir->op2;
630
+ break;
631
+ default:
632
+ lua_assert(ir->o <= IR_NE); /* Comparisons. */
633
+ split_emit(J, IRTGI(IR_HIOP), hiref, hisubst[ir->op2]);
634
+ break;
635
+ }
636
+ } else
637
+ #endif
638
+ #if LJ_SOFTFP
639
+ if (ir->o == IR_SLOAD) {
640
+ if ((nir->op2 & IRSLOAD_CONVERT)) { /* Convert from number to int. */
641
+ nir->op2 &= ~IRSLOAD_CONVERT;
642
+ if (!(nir->op2 & IRSLOAD_TYPECHECK))
643
+ nir->t.irt = IRT_INT; /* Drop guard. */
644
+ split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref);
645
+ ir->prev = split_num2int(J, nref, nref+1, irt_isguard(ir->t));
646
+ }
647
+ } else if (ir->o == IR_TOBIT) {
648
+ IRRef tmp, op1 = ir->op1;
649
+ J->cur.nins--;
650
+ #if LJ_LE
651
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), oir[op1].prev, hisubst[op1]);
652
+ #else
653
+ tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev);
654
+ #endif
655
+ ir->prev = split_emit(J, IRTI(IR_CALLN), tmp, IRCALL_lj_vm_tobit);
656
+ } else if (ir->o == IR_TOSTR) {
657
+ if (hisubst[ir->op1]) {
658
+ if (irref_isk(ir->op1))
659
+ nir->op1 = ir->op1;
660
+ else
661
+ split_emit(J, IRT(IR_HIOP, IRT_NIL), hisubst[ir->op1], nref);
662
+ }
663
+ } else if (ir->o == IR_HREF || ir->o == IR_NEWREF) {
664
+ if (irref_isk(ir->op2) && hisubst[ir->op2])
665
+ nir->op2 = ir->op2;
666
+ } else
667
+ #endif
668
+ if (ir->o == IR_CONV) { /* See above, too. */
669
+ IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
670
+ #if LJ_32 && LJ_HASFFI
671
+ if (st == IRT_I64 || st == IRT_U64) { /* Conversion from 64 bit int. */
672
+ #if LJ_SOFTFP
673
+ if (irt_isfloat(ir->t)) {
674
+ split_call_l(J, hisubst, oir, ir,
675
+ st == IRT_I64 ? IRCALL_fp64_l2f : IRCALL_fp64_ul2f);
676
+ J->cur.nins--; /* Drop unused HIOP. */
677
+ }
678
+ #else
679
+ if (irt_isfp(ir->t)) { /* 64 bit integer to FP conversion. */
680
+ ir->prev = split_emit(J, IRT(IR_HIOP, irt_type(ir->t)),
681
+ hisubst[ir->op1], nref);
682
+ }
683
+ #endif
684
+ else { /* Truncate to lower 32 bits. */
685
+ fwdlo:
686
+ ir->prev = nir->op1; /* Forward loword. */
687
+ /* Replace with NOP to avoid messing up the snapshot logic. */
688
+ nir->ot = IRT(IR_NOP, IRT_NIL);
689
+ nir->op1 = nir->op2 = 0;
690
+ }
691
+ }
692
+ #endif
693
+ #if LJ_SOFTFP && LJ_32 && LJ_HASFFI
694
+ else if (irt_isfloat(ir->t)) {
695
+ if (st == IRT_NUM) {
696
+ split_call_l(J, hisubst, oir, ir, IRCALL_softfp_d2f);
697
+ J->cur.nins--; /* Drop unused HIOP. */
698
+ } else {
699
+ nir->o = IR_CALLN;
700
+ nir->op2 = st == IRT_INT ? IRCALL_softfp_i2f : IRCALL_softfp_ui2f;
701
+ }
702
+ } else if (st == IRT_FLOAT) {
703
+ nir->o = IR_CALLN;
704
+ nir->op2 = irt_isint(ir->t) ? IRCALL_softfp_f2i : IRCALL_softfp_f2ui;
705
+ } else
706
+ #endif
707
+ #if LJ_SOFTFP
708
+ if (st == IRT_NUM || (LJ_32 && LJ_HASFFI && st == IRT_FLOAT)) {
709
+ if (irt_isguard(ir->t)) {
710
+ lua_assert(st == IRT_NUM && irt_isint(ir->t));
711
+ J->cur.nins--;
712
+ ir->prev = split_num2int(J, nir->op1, hisubst[ir->op1], 1);
713
+ } else {
714
+ split_call_l(J, hisubst, oir, ir,
715
+ #if LJ_32 && LJ_HASFFI
716
+ st == IRT_NUM ?
717
+ (irt_isint(ir->t) ? IRCALL_softfp_d2i : IRCALL_softfp_d2ui) :
718
+ (irt_isint(ir->t) ? IRCALL_softfp_f2i : IRCALL_softfp_f2ui)
719
+ #else
720
+ IRCALL_softfp_d2i
721
+ #endif
722
+ );
723
+ J->cur.nins--; /* Drop unused HIOP. */
724
+ }
725
+ }
726
+ #endif
727
+ } else if (ir->o == IR_CALLXS) {
728
+ IRRef hiref;
729
+ split_call:
730
+ hiref = hisubst[ir->op1];
731
+ if (hiref) {
732
+ IROpT ot = nir->ot;
733
+ IRRef op2 = nir->op2;
734
+ nir->ot = IRT(IR_CARG, IRT_NIL);
735
+ #if LJ_LE
736
+ nir->op2 = hiref;
737
+ #else
738
+ nir->op2 = nir->op1; nir->op1 = hiref;
739
+ #endif
740
+ ir->prev = nref = split_emit(J, ot, nref, op2);
741
+ }
742
+ if (LJ_SOFTFP ? irt_is64(ir->t) : irt_isint64(ir->t))
743
+ hi = split_emit(J,
744
+ IRT(IR_HIOP, (LJ_SOFTFP && irt_isnum(ir->t)) ? IRT_SOFTFP : IRT_INT),
745
+ nref, nref);
746
+ } else if (ir->o == IR_CARG) {
747
+ IRRef hiref = hisubst[ir->op1];
748
+ if (hiref) {
749
+ IRRef op2 = nir->op2;
750
+ #if LJ_LE
751
+ nir->op2 = hiref;
752
+ #else
753
+ nir->op2 = nir->op1; nir->op1 = hiref;
754
+ #endif
755
+ ir->prev = nref = split_emit(J, IRT(IR_CARG, IRT_NIL), nref, op2);
756
+ nir = IR(nref);
757
+ }
758
+ hiref = hisubst[ir->op2];
759
+ if (hiref) {
760
+ #if !LJ_TARGET_X86
761
+ int carg = 0;
762
+ IRIns *cir;
763
+ for (cir = IR(nir->op1); cir->o == IR_CARG; cir = IR(cir->op1))
764
+ carg++;
765
+ if ((carg & 1) == 0) { /* Align 64 bit arguments. */
766
+ IRRef op2 = nir->op2;
767
+ nir->op2 = REF_NIL;
768
+ nref = split_emit(J, IRT(IR_CARG, IRT_NIL), nref, op2);
769
+ nir = IR(nref);
770
+ }
771
+ #endif
772
+ #if LJ_BE
773
+ { IRRef tmp = nir->op2; nir->op2 = hiref; hiref = tmp; }
774
+ #endif
775
+ ir->prev = split_emit(J, IRT(IR_CARG, IRT_NIL), nref, hiref);
776
+ }
777
+ } else if (ir->o == IR_CNEWI) {
778
+ if (hisubst[ir->op2])
779
+ split_emit(J, IRT(IR_HIOP, IRT_NIL), nref, hisubst[ir->op2]);
780
+ } else if (ir->o == IR_LOOP) {
781
+ J->loopref = nref; /* Needed by assembler. */
782
+ }
783
+ hisubst[ref] = hi; /* Store hiword substitution. */
784
+ }
785
+ if (snref == nins) { /* Substitution for last snapshot. */
786
+ snap->ref = J->cur.nins;
787
+ split_subst_snap(J, snap, oir);
788
+ }
789
+
790
+ /* Add PHI marks. */
791
+ for (ref = J->cur.nins-1; ref >= REF_FIRST; ref--) {
792
+ IRIns *ir = IR(ref);
793
+ if (ir->o != IR_PHI) break;
794
+ if (!irref_isk(ir->op1)) irt_setphi(IR(ir->op1)->t);
795
+ if (ir->op2 > J->loopref) irt_setphi(IR(ir->op2)->t);
796
+ }
797
+ }
798
+
799
+ /* Protected callback for split pass. */
800
+ static TValue *cpsplit(lua_State *L, lua_CFunction dummy, void *ud)
801
+ {
802
+ jit_State *J = (jit_State *)ud;
803
+ split_ir(J);
804
+ UNUSED(L); UNUSED(dummy);
805
+ return NULL;
806
+ }
807
+
808
+ #if defined(LUA_USE_ASSERT) || LJ_SOFTFP
809
+ /* Slow, but sure way to check whether a SPLIT pass is needed. */
810
+ static int split_needsplit(jit_State *J)
811
+ {
812
+ IRIns *ir, *irend;
813
+ IRRef ref;
814
+ for (ir = IR(REF_FIRST), irend = IR(J->cur.nins); ir < irend; ir++)
815
+ if (LJ_SOFTFP ? irt_is64orfp(ir->t) : irt_isint64(ir->t))
816
+ return 1;
817
+ if (LJ_SOFTFP) {
818
+ for (ref = J->chain[IR_SLOAD]; ref; ref = IR(ref)->prev)
819
+ if ((IR(ref)->op2 & IRSLOAD_CONVERT))
820
+ return 1;
821
+ if (J->chain[IR_TOBIT])
822
+ return 1;
823
+ }
824
+ for (ref = J->chain[IR_CONV]; ref; ref = IR(ref)->prev) {
825
+ IRType st = (IR(ref)->op2 & IRCONV_SRCMASK);
826
+ if ((LJ_SOFTFP && (st == IRT_NUM || st == IRT_FLOAT)) ||
827
+ st == IRT_I64 || st == IRT_U64)
828
+ return 1;
829
+ }
830
+ return 0; /* Nope. */
831
+ }
832
+ #endif
833
+
834
+ /* SPLIT pass. */
835
+ void lj_opt_split(jit_State *J)
836
+ {
837
+ #if LJ_SOFTFP
838
+ if (!J->needsplit)
839
+ J->needsplit = split_needsplit(J);
840
+ #else
841
+ lua_assert(J->needsplit >= split_needsplit(J)); /* Verify flag. */
842
+ #endif
843
+ if (J->needsplit) {
844
+ int errcode = lj_vm_cpcall(J->L, NULL, J, cpsplit);
845
+ if (errcode) {
846
+ /* Completely reset the trace to avoid inconsistent dump on abort. */
847
+ J->cur.nins = J->cur.nk = REF_BASE;
848
+ J->cur.nsnap = 0;
849
+ lj_err_throw(J->L, errcode); /* Propagate errors. */
850
+ }
851
+ }
852
+ }
853
+
854
+ #undef IR
855
+
856
+ #endif