immunio 0.15.4 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (454) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +0 -27
  3. data/ext/immunio/Rakefile +9 -0
  4. data/lib/immunio/plugins/active_record.rb +1 -1
  5. data/lib/immunio/plugins/active_record_relation.rb +1 -1
  6. data/lib/immunio/plugins/environment_reporter.rb +20 -0
  7. data/lib/immunio/rufus_lua_ext/ref.rb +1 -3
  8. data/lib/immunio/version.rb +1 -1
  9. data/lib/immunio/vm.rb +1 -2
  10. data/lua-hooks/Makefile +97 -0
  11. data/lua-hooks/ext/all.c +41 -52
  12. data/lua-hooks/ext/all.o +0 -0
  13. data/lua-hooks/ext/libinjection/libinjection_html5.o +0 -0
  14. data/lua-hooks/ext/libinjection/libinjection_sqli.o +0 -0
  15. data/lua-hooks/ext/libinjection/libinjection_xss.o +0 -0
  16. data/lua-hooks/ext/libinjection/lualib.c +2 -2
  17. data/lua-hooks/ext/lpeg/lpcap.c +2 -2
  18. data/lua-hooks/ext/lpeg/lpcap.o +0 -0
  19. data/lua-hooks/ext/lpeg/lpcode.c +2 -2
  20. data/lua-hooks/ext/lpeg/lpcode.h +1 -1
  21. data/lua-hooks/ext/lpeg/lpcode.o +0 -0
  22. data/lua-hooks/ext/lpeg/lpprint.o +0 -0
  23. data/lua-hooks/ext/lpeg/lptree.c +2 -2
  24. data/lua-hooks/ext/lpeg/lptypes.h +1 -1
  25. data/lua-hooks/ext/lpeg/lpvm.c +2 -2
  26. data/lua-hooks/ext/lpeg/lpvm.o +0 -0
  27. data/lua-hooks/ext/lua-cmsgpack/lua_cmsgpack.c +16 -3
  28. data/lua-hooks/ext/lua-snapshot/snapshot.c +14 -7
  29. data/lua-hooks/ext/luajit/COPYRIGHT +56 -0
  30. data/lua-hooks/ext/luajit/Makefile +159 -0
  31. data/lua-hooks/ext/luajit/README +16 -0
  32. data/lua-hooks/ext/luajit/doc/bluequad-print.css +166 -0
  33. data/lua-hooks/ext/luajit/doc/bluequad.css +325 -0
  34. data/lua-hooks/ext/luajit/doc/changes.html +804 -0
  35. data/lua-hooks/ext/luajit/doc/contact.html +104 -0
  36. data/lua-hooks/ext/luajit/doc/ext_c_api.html +189 -0
  37. data/lua-hooks/ext/luajit/doc/ext_ffi.html +332 -0
  38. data/lua-hooks/ext/luajit/doc/ext_ffi_api.html +570 -0
  39. data/lua-hooks/ext/luajit/doc/ext_ffi_semantics.html +1261 -0
  40. data/lua-hooks/ext/luajit/doc/ext_ffi_tutorial.html +603 -0
  41. data/lua-hooks/ext/luajit/doc/ext_jit.html +201 -0
  42. data/lua-hooks/ext/luajit/doc/ext_profiler.html +365 -0
  43. data/lua-hooks/ext/luajit/doc/extensions.html +448 -0
  44. data/lua-hooks/ext/luajit/doc/faq.html +186 -0
  45. data/lua-hooks/ext/luajit/doc/img/contact.png +0 -0
  46. data/lua-hooks/ext/luajit/doc/install.html +659 -0
  47. data/lua-hooks/ext/luajit/doc/luajit.html +236 -0
  48. data/lua-hooks/ext/luajit/doc/running.html +309 -0
  49. data/lua-hooks/ext/luajit/doc/status.html +118 -0
  50. data/lua-hooks/ext/luajit/dynasm/dasm_arm.h +456 -0
  51. data/lua-hooks/ext/luajit/dynasm/dasm_arm.lua +1125 -0
  52. data/lua-hooks/ext/luajit/dynasm/dasm_arm64.h +518 -0
  53. data/lua-hooks/ext/luajit/dynasm/dasm_arm64.lua +1166 -0
  54. data/lua-hooks/ext/luajit/dynasm/dasm_mips.h +416 -0
  55. data/lua-hooks/ext/luajit/dynasm/dasm_mips.lua +953 -0
  56. data/lua-hooks/ext/luajit/dynasm/dasm_ppc.h +419 -0
  57. data/lua-hooks/ext/luajit/dynasm/dasm_ppc.lua +1919 -0
  58. data/lua-hooks/ext/luajit/dynasm/dasm_proto.h +83 -0
  59. data/lua-hooks/ext/luajit/dynasm/dasm_x64.lua +12 -0
  60. data/lua-hooks/ext/luajit/dynasm/dasm_x86.h +471 -0
  61. data/lua-hooks/ext/luajit/dynasm/dasm_x86.lua +1945 -0
  62. data/lua-hooks/ext/luajit/dynasm/dynasm.lua +1094 -0
  63. data/lua-hooks/ext/luajit/etc/luajit.1 +88 -0
  64. data/lua-hooks/ext/luajit/etc/luajit.pc +25 -0
  65. data/lua-hooks/ext/luajit/src/Makefile +697 -0
  66. data/lua-hooks/ext/luajit/src/Makefile.dep +244 -0
  67. data/lua-hooks/ext/luajit/src/host/README +4 -0
  68. data/lua-hooks/ext/luajit/src/host/buildvm +0 -0
  69. data/lua-hooks/ext/luajit/src/host/buildvm.c +518 -0
  70. data/lua-hooks/ext/luajit/src/host/buildvm.h +105 -0
  71. data/lua-hooks/ext/luajit/src/host/buildvm.o +0 -0
  72. data/lua-hooks/ext/luajit/src/host/buildvm_arch.h +7449 -0
  73. data/lua-hooks/ext/luajit/src/host/buildvm_asm.c +345 -0
  74. data/lua-hooks/ext/luajit/src/host/buildvm_asm.o +0 -0
  75. data/lua-hooks/ext/luajit/src/host/buildvm_fold.c +229 -0
  76. data/lua-hooks/ext/luajit/src/host/buildvm_fold.o +0 -0
  77. data/lua-hooks/ext/luajit/src/host/buildvm_lib.c +457 -0
  78. data/lua-hooks/ext/luajit/src/host/buildvm_lib.o +0 -0
  79. data/lua-hooks/ext/luajit/src/host/buildvm_libbc.h +45 -0
  80. data/lua-hooks/ext/luajit/src/host/buildvm_peobj.c +368 -0
  81. data/lua-hooks/ext/luajit/src/host/buildvm_peobj.o +0 -0
  82. data/lua-hooks/ext/luajit/src/host/genlibbc.lua +197 -0
  83. data/lua-hooks/ext/luajit/src/host/genminilua.lua +428 -0
  84. data/lua-hooks/ext/luajit/src/host/minilua +0 -0
  85. data/lua-hooks/ext/luajit/src/host/minilua.c +7770 -0
  86. data/lua-hooks/ext/luajit/src/host/minilua.o +0 -0
  87. data/lua-hooks/ext/luajit/src/jit/bc.lua +190 -0
  88. data/lua-hooks/ext/luajit/src/jit/bcsave.lua +661 -0
  89. data/lua-hooks/ext/luajit/src/jit/dis_arm.lua +689 -0
  90. data/lua-hooks/ext/luajit/src/jit/dis_mips.lua +428 -0
  91. data/lua-hooks/ext/luajit/src/jit/dis_mipsel.lua +17 -0
  92. data/lua-hooks/ext/luajit/src/jit/dis_ppc.lua +591 -0
  93. data/lua-hooks/ext/luajit/src/jit/dis_x64.lua +17 -0
  94. data/lua-hooks/ext/luajit/src/jit/dis_x86.lua +838 -0
  95. data/lua-hooks/ext/luajit/src/jit/dump.lua +706 -0
  96. data/lua-hooks/ext/luajit/src/jit/p.lua +310 -0
  97. data/lua-hooks/ext/luajit/src/jit/v.lua +170 -0
  98. data/lua-hooks/ext/luajit/src/jit/vmdef.lua +362 -0
  99. data/lua-hooks/ext/luajit/src/jit/zone.lua +45 -0
  100. data/lua-hooks/ext/{lua → luajit/src}/lauxlib.h +10 -17
  101. data/lua-hooks/ext/luajit/src/lib_aux.c +356 -0
  102. data/lua-hooks/ext/luajit/src/lib_aux.o +0 -0
  103. data/lua-hooks/ext/luajit/src/lib_aux_dyn.o +0 -0
  104. data/lua-hooks/ext/luajit/src/lib_base.c +664 -0
  105. data/lua-hooks/ext/luajit/src/lib_base.o +0 -0
  106. data/lua-hooks/ext/luajit/src/lib_base_dyn.o +0 -0
  107. data/lua-hooks/ext/luajit/src/lib_bit.c +180 -0
  108. data/lua-hooks/ext/luajit/src/lib_bit.o +0 -0
  109. data/lua-hooks/ext/luajit/src/lib_bit_dyn.o +0 -0
  110. data/lua-hooks/ext/luajit/src/lib_debug.c +405 -0
  111. data/lua-hooks/ext/luajit/src/lib_debug.o +0 -0
  112. data/lua-hooks/ext/luajit/src/lib_debug_dyn.o +0 -0
  113. data/lua-hooks/ext/luajit/src/lib_ffi.c +872 -0
  114. data/lua-hooks/ext/luajit/src/lib_ffi.o +0 -0
  115. data/lua-hooks/ext/luajit/src/lib_ffi_dyn.o +0 -0
  116. data/lua-hooks/ext/luajit/src/lib_init.c +55 -0
  117. data/lua-hooks/ext/luajit/src/lib_init.o +0 -0
  118. data/lua-hooks/ext/luajit/src/lib_init_dyn.o +0 -0
  119. data/lua-hooks/ext/luajit/src/lib_io.c +541 -0
  120. data/lua-hooks/ext/luajit/src/lib_io.o +0 -0
  121. data/lua-hooks/ext/luajit/src/lib_io_dyn.o +0 -0
  122. data/lua-hooks/ext/luajit/src/lib_jit.c +767 -0
  123. data/lua-hooks/ext/luajit/src/lib_jit.o +0 -0
  124. data/lua-hooks/ext/luajit/src/lib_jit_dyn.o +0 -0
  125. data/lua-hooks/ext/luajit/src/lib_math.c +230 -0
  126. data/lua-hooks/ext/luajit/src/lib_math.o +0 -0
  127. data/lua-hooks/ext/luajit/src/lib_math_dyn.o +0 -0
  128. data/lua-hooks/ext/luajit/src/lib_os.c +292 -0
  129. data/lua-hooks/ext/luajit/src/lib_os.o +0 -0
  130. data/lua-hooks/ext/luajit/src/lib_os_dyn.o +0 -0
  131. data/lua-hooks/ext/luajit/src/lib_package.c +610 -0
  132. data/lua-hooks/ext/luajit/src/lib_package.o +0 -0
  133. data/lua-hooks/ext/luajit/src/lib_package_dyn.o +0 -0
  134. data/lua-hooks/ext/luajit/src/lib_string.c +752 -0
  135. data/lua-hooks/ext/luajit/src/lib_string.o +0 -0
  136. data/lua-hooks/ext/luajit/src/lib_string_dyn.o +0 -0
  137. data/lua-hooks/ext/luajit/src/lib_table.c +307 -0
  138. data/lua-hooks/ext/luajit/src/lib_table.o +0 -0
  139. data/lua-hooks/ext/luajit/src/lib_table_dyn.o +0 -0
  140. data/lua-hooks/ext/luajit/src/libluajit.a +0 -0
  141. data/lua-hooks/ext/luajit/src/libluajit.so +0 -0
  142. data/lua-hooks/ext/luajit/src/lj.supp +26 -0
  143. data/lua-hooks/ext/luajit/src/lj_alloc.c +1398 -0
  144. data/lua-hooks/ext/luajit/src/lj_alloc.h +17 -0
  145. data/lua-hooks/ext/luajit/src/lj_alloc.o +0 -0
  146. data/lua-hooks/ext/luajit/src/lj_alloc_dyn.o +0 -0
  147. data/lua-hooks/ext/luajit/src/lj_api.c +1210 -0
  148. data/lua-hooks/ext/luajit/src/lj_api.o +0 -0
  149. data/lua-hooks/ext/luajit/src/lj_api_dyn.o +0 -0
  150. data/lua-hooks/ext/luajit/src/lj_arch.h +509 -0
  151. data/lua-hooks/ext/luajit/src/lj_asm.c +2278 -0
  152. data/lua-hooks/ext/luajit/src/lj_asm.h +17 -0
  153. data/lua-hooks/ext/luajit/src/lj_asm.o +0 -0
  154. data/lua-hooks/ext/luajit/src/lj_asm_arm.h +2217 -0
  155. data/lua-hooks/ext/luajit/src/lj_asm_dyn.o +0 -0
  156. data/lua-hooks/ext/luajit/src/lj_asm_mips.h +1833 -0
  157. data/lua-hooks/ext/luajit/src/lj_asm_ppc.h +2015 -0
  158. data/lua-hooks/ext/luajit/src/lj_asm_x86.h +2634 -0
  159. data/lua-hooks/ext/luajit/src/lj_bc.c +14 -0
  160. data/lua-hooks/ext/luajit/src/lj_bc.h +265 -0
  161. data/lua-hooks/ext/luajit/src/lj_bc.o +0 -0
  162. data/lua-hooks/ext/luajit/src/lj_bc_dyn.o +0 -0
  163. data/lua-hooks/ext/luajit/src/lj_bcdef.h +220 -0
  164. data/lua-hooks/ext/luajit/src/lj_bcdump.h +68 -0
  165. data/lua-hooks/ext/luajit/src/lj_bcread.c +457 -0
  166. data/lua-hooks/ext/luajit/src/lj_bcread.o +0 -0
  167. data/lua-hooks/ext/luajit/src/lj_bcread_dyn.o +0 -0
  168. data/lua-hooks/ext/luajit/src/lj_bcwrite.c +361 -0
  169. data/lua-hooks/ext/luajit/src/lj_bcwrite.o +0 -0
  170. data/lua-hooks/ext/luajit/src/lj_bcwrite_dyn.o +0 -0
  171. data/lua-hooks/ext/luajit/src/lj_buf.c +234 -0
  172. data/lua-hooks/ext/luajit/src/lj_buf.h +105 -0
  173. data/lua-hooks/ext/luajit/src/lj_buf.o +0 -0
  174. data/lua-hooks/ext/luajit/src/lj_buf_dyn.o +0 -0
  175. data/lua-hooks/ext/luajit/src/lj_carith.c +429 -0
  176. data/lua-hooks/ext/luajit/src/lj_carith.h +37 -0
  177. data/lua-hooks/ext/luajit/src/lj_carith.o +0 -0
  178. data/lua-hooks/ext/luajit/src/lj_carith_dyn.o +0 -0
  179. data/lua-hooks/ext/luajit/src/lj_ccall.c +984 -0
  180. data/lua-hooks/ext/luajit/src/lj_ccall.h +178 -0
  181. data/lua-hooks/ext/luajit/src/lj_ccall.o +0 -0
  182. data/lua-hooks/ext/luajit/src/lj_ccall_dyn.o +0 -0
  183. data/lua-hooks/ext/luajit/src/lj_ccallback.c +712 -0
  184. data/lua-hooks/ext/luajit/src/lj_ccallback.h +25 -0
  185. data/lua-hooks/ext/luajit/src/lj_ccallback.o +0 -0
  186. data/lua-hooks/ext/luajit/src/lj_ccallback_dyn.o +0 -0
  187. data/lua-hooks/ext/luajit/src/lj_cconv.c +752 -0
  188. data/lua-hooks/ext/luajit/src/lj_cconv.h +70 -0
  189. data/lua-hooks/ext/luajit/src/lj_cconv.o +0 -0
  190. data/lua-hooks/ext/luajit/src/lj_cconv_dyn.o +0 -0
  191. data/lua-hooks/ext/luajit/src/lj_cdata.c +288 -0
  192. data/lua-hooks/ext/luajit/src/lj_cdata.h +76 -0
  193. data/lua-hooks/ext/luajit/src/lj_cdata.o +0 -0
  194. data/lua-hooks/ext/luajit/src/lj_cdata_dyn.o +0 -0
  195. data/lua-hooks/ext/luajit/src/lj_char.c +43 -0
  196. data/lua-hooks/ext/luajit/src/lj_char.h +42 -0
  197. data/lua-hooks/ext/luajit/src/lj_char.o +0 -0
  198. data/lua-hooks/ext/luajit/src/lj_char_dyn.o +0 -0
  199. data/lua-hooks/ext/luajit/src/lj_clib.c +418 -0
  200. data/lua-hooks/ext/luajit/src/lj_clib.h +29 -0
  201. data/lua-hooks/ext/luajit/src/lj_clib.o +0 -0
  202. data/lua-hooks/ext/luajit/src/lj_clib_dyn.o +0 -0
  203. data/lua-hooks/ext/luajit/src/lj_cparse.c +1862 -0
  204. data/lua-hooks/ext/luajit/src/lj_cparse.h +65 -0
  205. data/lua-hooks/ext/luajit/src/lj_cparse.o +0 -0
  206. data/lua-hooks/ext/luajit/src/lj_cparse_dyn.o +0 -0
  207. data/lua-hooks/ext/luajit/src/lj_crecord.c +1834 -0
  208. data/lua-hooks/ext/luajit/src/lj_crecord.h +38 -0
  209. data/lua-hooks/ext/luajit/src/lj_crecord.o +0 -0
  210. data/lua-hooks/ext/luajit/src/lj_crecord_dyn.o +0 -0
  211. data/lua-hooks/ext/luajit/src/lj_ctype.c +635 -0
  212. data/lua-hooks/ext/luajit/src/lj_ctype.h +461 -0
  213. data/lua-hooks/ext/luajit/src/lj_ctype.o +0 -0
  214. data/lua-hooks/ext/luajit/src/lj_ctype_dyn.o +0 -0
  215. data/lua-hooks/ext/luajit/src/lj_debug.c +699 -0
  216. data/lua-hooks/ext/luajit/src/lj_debug.h +65 -0
  217. data/lua-hooks/ext/luajit/src/lj_debug.o +0 -0
  218. data/lua-hooks/ext/luajit/src/lj_debug_dyn.o +0 -0
  219. data/lua-hooks/ext/luajit/src/lj_def.h +365 -0
  220. data/lua-hooks/ext/luajit/src/lj_dispatch.c +557 -0
  221. data/lua-hooks/ext/luajit/src/lj_dispatch.h +138 -0
  222. data/lua-hooks/ext/luajit/src/lj_dispatch.o +0 -0
  223. data/lua-hooks/ext/luajit/src/lj_dispatch_dyn.o +0 -0
  224. data/lua-hooks/ext/luajit/src/lj_emit_arm.h +356 -0
  225. data/lua-hooks/ext/luajit/src/lj_emit_mips.h +211 -0
  226. data/lua-hooks/ext/luajit/src/lj_emit_ppc.h +238 -0
  227. data/lua-hooks/ext/luajit/src/lj_emit_x86.h +462 -0
  228. data/lua-hooks/ext/luajit/src/lj_err.c +794 -0
  229. data/lua-hooks/ext/luajit/src/lj_err.h +41 -0
  230. data/lua-hooks/ext/luajit/src/lj_err.o +0 -0
  231. data/lua-hooks/ext/luajit/src/lj_err_dyn.o +0 -0
  232. data/lua-hooks/ext/luajit/src/lj_errmsg.h +190 -0
  233. data/lua-hooks/ext/luajit/src/lj_ff.h +18 -0
  234. data/lua-hooks/ext/luajit/src/lj_ffdef.h +209 -0
  235. data/lua-hooks/ext/luajit/src/lj_ffrecord.c +1247 -0
  236. data/lua-hooks/ext/luajit/src/lj_ffrecord.h +24 -0
  237. data/lua-hooks/ext/luajit/src/lj_ffrecord.o +0 -0
  238. data/lua-hooks/ext/luajit/src/lj_ffrecord_dyn.o +0 -0
  239. data/lua-hooks/ext/luajit/src/lj_folddef.h +1138 -0
  240. data/lua-hooks/ext/luajit/src/lj_frame.h +259 -0
  241. data/lua-hooks/ext/luajit/src/lj_func.c +185 -0
  242. data/lua-hooks/ext/luajit/src/lj_func.h +24 -0
  243. data/lua-hooks/ext/luajit/src/lj_func.o +0 -0
  244. data/lua-hooks/ext/luajit/src/lj_func_dyn.o +0 -0
  245. data/lua-hooks/ext/luajit/src/lj_gc.c +845 -0
  246. data/lua-hooks/ext/luajit/src/lj_gc.h +134 -0
  247. data/lua-hooks/ext/luajit/src/lj_gc.o +0 -0
  248. data/lua-hooks/ext/luajit/src/lj_gc_dyn.o +0 -0
  249. data/lua-hooks/ext/luajit/src/lj_gdbjit.c +787 -0
  250. data/lua-hooks/ext/luajit/src/lj_gdbjit.h +22 -0
  251. data/lua-hooks/ext/luajit/src/lj_gdbjit.o +0 -0
  252. data/lua-hooks/ext/luajit/src/lj_gdbjit_dyn.o +0 -0
  253. data/lua-hooks/ext/luajit/src/lj_ir.c +505 -0
  254. data/lua-hooks/ext/luajit/src/lj_ir.h +577 -0
  255. data/lua-hooks/ext/luajit/src/lj_ir.o +0 -0
  256. data/lua-hooks/ext/luajit/src/lj_ir_dyn.o +0 -0
  257. data/lua-hooks/ext/luajit/src/lj_ircall.h +321 -0
  258. data/lua-hooks/ext/luajit/src/lj_iropt.h +161 -0
  259. data/lua-hooks/ext/luajit/src/lj_jit.h +440 -0
  260. data/lua-hooks/ext/luajit/src/lj_lex.c +482 -0
  261. data/lua-hooks/ext/luajit/src/lj_lex.h +86 -0
  262. data/lua-hooks/ext/luajit/src/lj_lex.o +0 -0
  263. data/lua-hooks/ext/luajit/src/lj_lex_dyn.o +0 -0
  264. data/lua-hooks/ext/luajit/src/lj_lib.c +303 -0
  265. data/lua-hooks/ext/luajit/src/lj_lib.h +115 -0
  266. data/lua-hooks/ext/luajit/src/lj_lib.o +0 -0
  267. data/lua-hooks/ext/luajit/src/lj_lib_dyn.o +0 -0
  268. data/lua-hooks/ext/luajit/src/lj_libdef.h +414 -0
  269. data/lua-hooks/ext/luajit/src/lj_load.c +168 -0
  270. data/lua-hooks/ext/luajit/src/lj_load.o +0 -0
  271. data/lua-hooks/ext/luajit/src/lj_load_dyn.o +0 -0
  272. data/lua-hooks/ext/luajit/src/lj_mcode.c +386 -0
  273. data/lua-hooks/ext/luajit/src/lj_mcode.h +30 -0
  274. data/lua-hooks/ext/luajit/src/lj_mcode.o +0 -0
  275. data/lua-hooks/ext/luajit/src/lj_mcode_dyn.o +0 -0
  276. data/lua-hooks/ext/luajit/src/lj_meta.c +477 -0
  277. data/lua-hooks/ext/luajit/src/lj_meta.h +38 -0
  278. data/lua-hooks/ext/luajit/src/lj_meta.o +0 -0
  279. data/lua-hooks/ext/luajit/src/lj_meta_dyn.o +0 -0
  280. data/lua-hooks/ext/luajit/src/lj_obj.c +50 -0
  281. data/lua-hooks/ext/luajit/src/lj_obj.h +976 -0
  282. data/lua-hooks/ext/luajit/src/lj_obj.o +0 -0
  283. data/lua-hooks/ext/luajit/src/lj_obj_dyn.o +0 -0
  284. data/lua-hooks/ext/luajit/src/lj_opt_dce.c +78 -0
  285. data/lua-hooks/ext/luajit/src/lj_opt_dce.o +0 -0
  286. data/lua-hooks/ext/luajit/src/lj_opt_dce_dyn.o +0 -0
  287. data/lua-hooks/ext/luajit/src/lj_opt_fold.c +2488 -0
  288. data/lua-hooks/ext/luajit/src/lj_opt_fold.o +0 -0
  289. data/lua-hooks/ext/luajit/src/lj_opt_fold_dyn.o +0 -0
  290. data/lua-hooks/ext/luajit/src/lj_opt_loop.c +449 -0
  291. data/lua-hooks/ext/luajit/src/lj_opt_loop.o +0 -0
  292. data/lua-hooks/ext/luajit/src/lj_opt_loop_dyn.o +0 -0
  293. data/lua-hooks/ext/luajit/src/lj_opt_mem.c +935 -0
  294. data/lua-hooks/ext/luajit/src/lj_opt_mem.o +0 -0
  295. data/lua-hooks/ext/luajit/src/lj_opt_mem_dyn.o +0 -0
  296. data/lua-hooks/ext/luajit/src/lj_opt_narrow.c +652 -0
  297. data/lua-hooks/ext/luajit/src/lj_opt_narrow.o +0 -0
  298. data/lua-hooks/ext/luajit/src/lj_opt_narrow_dyn.o +0 -0
  299. data/lua-hooks/ext/luajit/src/lj_opt_sink.c +245 -0
  300. data/lua-hooks/ext/luajit/src/lj_opt_sink.o +0 -0
  301. data/lua-hooks/ext/luajit/src/lj_opt_sink_dyn.o +0 -0
  302. data/lua-hooks/ext/luajit/src/lj_opt_split.c +856 -0
  303. data/lua-hooks/ext/luajit/src/lj_opt_split.o +0 -0
  304. data/lua-hooks/ext/luajit/src/lj_opt_split_dyn.o +0 -0
  305. data/lua-hooks/ext/luajit/src/lj_parse.c +2725 -0
  306. data/lua-hooks/ext/luajit/src/lj_parse.h +18 -0
  307. data/lua-hooks/ext/luajit/src/lj_parse.o +0 -0
  308. data/lua-hooks/ext/luajit/src/lj_parse_dyn.o +0 -0
  309. data/lua-hooks/ext/luajit/src/lj_profile.c +368 -0
  310. data/lua-hooks/ext/luajit/src/lj_profile.h +21 -0
  311. data/lua-hooks/ext/luajit/src/lj_profile.o +0 -0
  312. data/lua-hooks/ext/luajit/src/lj_profile_dyn.o +0 -0
  313. data/lua-hooks/ext/luajit/src/lj_recdef.h +270 -0
  314. data/lua-hooks/ext/luajit/src/lj_record.c +2554 -0
  315. data/lua-hooks/ext/luajit/src/lj_record.h +45 -0
  316. data/lua-hooks/ext/luajit/src/lj_record.o +0 -0
  317. data/lua-hooks/ext/luajit/src/lj_record_dyn.o +0 -0
  318. data/lua-hooks/ext/luajit/src/lj_snap.c +870 -0
  319. data/lua-hooks/ext/luajit/src/lj_snap.h +34 -0
  320. data/lua-hooks/ext/luajit/src/lj_snap.o +0 -0
  321. data/lua-hooks/ext/luajit/src/lj_snap_dyn.o +0 -0
  322. data/lua-hooks/ext/luajit/src/lj_state.c +300 -0
  323. data/lua-hooks/ext/luajit/src/lj_state.h +35 -0
  324. data/lua-hooks/ext/luajit/src/lj_state.o +0 -0
  325. data/lua-hooks/ext/luajit/src/lj_state_dyn.o +0 -0
  326. data/lua-hooks/ext/luajit/src/lj_str.c +197 -0
  327. data/lua-hooks/ext/luajit/src/lj_str.h +27 -0
  328. data/lua-hooks/ext/luajit/src/lj_str.o +0 -0
  329. data/lua-hooks/ext/luajit/src/lj_str_dyn.o +0 -0
  330. data/lua-hooks/ext/luajit/src/lj_strfmt.c +554 -0
  331. data/lua-hooks/ext/luajit/src/lj_strfmt.h +125 -0
  332. data/lua-hooks/ext/luajit/src/lj_strfmt.o +0 -0
  333. data/lua-hooks/ext/luajit/src/lj_strfmt_dyn.o +0 -0
  334. data/lua-hooks/ext/luajit/src/lj_strscan.c +547 -0
  335. data/lua-hooks/ext/luajit/src/lj_strscan.h +39 -0
  336. data/lua-hooks/ext/luajit/src/lj_strscan.o +0 -0
  337. data/lua-hooks/ext/luajit/src/lj_strscan_dyn.o +0 -0
  338. data/lua-hooks/ext/luajit/src/lj_tab.c +666 -0
  339. data/lua-hooks/ext/luajit/src/lj_tab.h +73 -0
  340. data/lua-hooks/ext/luajit/src/lj_tab.o +0 -0
  341. data/lua-hooks/ext/luajit/src/lj_tab_dyn.o +0 -0
  342. data/lua-hooks/ext/luajit/src/lj_target.h +164 -0
  343. data/lua-hooks/ext/luajit/src/lj_target_arm.h +270 -0
  344. data/lua-hooks/ext/luajit/src/lj_target_arm64.h +97 -0
  345. data/lua-hooks/ext/luajit/src/lj_target_mips.h +260 -0
  346. data/lua-hooks/ext/luajit/src/lj_target_ppc.h +280 -0
  347. data/lua-hooks/ext/luajit/src/lj_target_x86.h +345 -0
  348. data/lua-hooks/ext/luajit/src/lj_trace.c +859 -0
  349. data/lua-hooks/ext/luajit/src/lj_trace.h +54 -0
  350. data/lua-hooks/ext/luajit/src/lj_trace.o +0 -0
  351. data/lua-hooks/ext/luajit/src/lj_trace_dyn.o +0 -0
  352. data/lua-hooks/ext/luajit/src/lj_traceerr.h +63 -0
  353. data/lua-hooks/ext/luajit/src/lj_udata.c +34 -0
  354. data/lua-hooks/ext/luajit/src/lj_udata.h +14 -0
  355. data/lua-hooks/ext/luajit/src/lj_udata.o +0 -0
  356. data/lua-hooks/ext/luajit/src/lj_udata_dyn.o +0 -0
  357. data/lua-hooks/ext/luajit/src/lj_vm.S +2730 -0
  358. data/lua-hooks/ext/luajit/src/lj_vm.h +114 -0
  359. data/lua-hooks/ext/luajit/src/lj_vm.o +0 -0
  360. data/lua-hooks/ext/luajit/src/lj_vm_dyn.o +0 -0
  361. data/lua-hooks/ext/luajit/src/lj_vmevent.c +58 -0
  362. data/lua-hooks/ext/luajit/src/lj_vmevent.h +59 -0
  363. data/lua-hooks/ext/luajit/src/lj_vmevent.o +0 -0
  364. data/lua-hooks/ext/luajit/src/lj_vmevent_dyn.o +0 -0
  365. data/lua-hooks/ext/luajit/src/lj_vmmath.c +152 -0
  366. data/lua-hooks/ext/luajit/src/lj_vmmath.o +0 -0
  367. data/lua-hooks/ext/luajit/src/lj_vmmath_dyn.o +0 -0
  368. data/lua-hooks/ext/luajit/src/ljamalg.c +96 -0
  369. data/lua-hooks/ext/{lua → luajit/src}/lua.h +12 -7
  370. data/lua-hooks/ext/luajit/src/lua.hpp +9 -0
  371. data/lua-hooks/ext/luajit/src/luaconf.h +156 -0
  372. data/lua-hooks/ext/luajit/src/luajit +0 -0
  373. data/lua-hooks/ext/luajit/src/luajit.c +570 -0
  374. data/lua-hooks/ext/luajit/src/luajit.h +79 -0
  375. data/lua-hooks/ext/luajit/src/luajit.o +0 -0
  376. data/lua-hooks/ext/luajit/src/lualib.h +43 -0
  377. data/lua-hooks/ext/luajit/src/msvcbuild.bat +114 -0
  378. data/lua-hooks/ext/luajit/src/ps4build.bat +103 -0
  379. data/lua-hooks/ext/luajit/src/psvitabuild.bat +93 -0
  380. data/lua-hooks/ext/luajit/src/vm_arm.dasc +4585 -0
  381. data/lua-hooks/ext/luajit/src/vm_arm64.dasc +3764 -0
  382. data/lua-hooks/ext/luajit/src/vm_mips.dasc +4355 -0
  383. data/lua-hooks/ext/luajit/src/vm_ppc.dasc +5252 -0
  384. data/lua-hooks/ext/luajit/src/vm_x64.dasc +4902 -0
  385. data/lua-hooks/ext/luajit/src/vm_x86.dasc +5710 -0
  386. data/lua-hooks/ext/luajit/src/xb1build.bat +101 -0
  387. data/lua-hooks/ext/luajit/src/xedkbuild.bat +92 -0
  388. data/lua-hooks/ext/luautf8/lutf8lib.c +3 -3
  389. data/lua-hooks/lib/boot.lua +37 -2
  390. metadata +372 -69
  391. data/lua-hooks/ext/bitop/README +0 -22
  392. data/lua-hooks/ext/bitop/bit.c +0 -189
  393. data/lua-hooks/ext/extconf.rb +0 -38
  394. data/lua-hooks/ext/lua/COPYRIGHT +0 -34
  395. data/lua-hooks/ext/lua/lapi.c +0 -1087
  396. data/lua-hooks/ext/lua/lapi.h +0 -16
  397. data/lua-hooks/ext/lua/lauxlib.c +0 -652
  398. data/lua-hooks/ext/lua/lbaselib.c +0 -659
  399. data/lua-hooks/ext/lua/lcode.c +0 -831
  400. data/lua-hooks/ext/lua/lcode.h +0 -76
  401. data/lua-hooks/ext/lua/ldblib.c +0 -398
  402. data/lua-hooks/ext/lua/ldebug.c +0 -638
  403. data/lua-hooks/ext/lua/ldebug.h +0 -33
  404. data/lua-hooks/ext/lua/ldo.c +0 -519
  405. data/lua-hooks/ext/lua/ldo.h +0 -57
  406. data/lua-hooks/ext/lua/ldump.c +0 -164
  407. data/lua-hooks/ext/lua/lfunc.c +0 -174
  408. data/lua-hooks/ext/lua/lfunc.h +0 -34
  409. data/lua-hooks/ext/lua/lgc.c +0 -710
  410. data/lua-hooks/ext/lua/lgc.h +0 -110
  411. data/lua-hooks/ext/lua/linit.c +0 -38
  412. data/lua-hooks/ext/lua/liolib.c +0 -556
  413. data/lua-hooks/ext/lua/llex.c +0 -463
  414. data/lua-hooks/ext/lua/llex.h +0 -81
  415. data/lua-hooks/ext/lua/llimits.h +0 -128
  416. data/lua-hooks/ext/lua/lmathlib.c +0 -263
  417. data/lua-hooks/ext/lua/lmem.c +0 -86
  418. data/lua-hooks/ext/lua/lmem.h +0 -49
  419. data/lua-hooks/ext/lua/loadlib.c +0 -705
  420. data/lua-hooks/ext/lua/loadlib_rel.c +0 -760
  421. data/lua-hooks/ext/lua/lobject.c +0 -214
  422. data/lua-hooks/ext/lua/lobject.h +0 -381
  423. data/lua-hooks/ext/lua/lopcodes.c +0 -102
  424. data/lua-hooks/ext/lua/lopcodes.h +0 -268
  425. data/lua-hooks/ext/lua/loslib.c +0 -243
  426. data/lua-hooks/ext/lua/lparser.c +0 -1339
  427. data/lua-hooks/ext/lua/lparser.h +0 -82
  428. data/lua-hooks/ext/lua/lstate.c +0 -214
  429. data/lua-hooks/ext/lua/lstate.h +0 -169
  430. data/lua-hooks/ext/lua/lstring.c +0 -111
  431. data/lua-hooks/ext/lua/lstring.h +0 -31
  432. data/lua-hooks/ext/lua/lstrlib.c +0 -871
  433. data/lua-hooks/ext/lua/ltable.c +0 -588
  434. data/lua-hooks/ext/lua/ltable.h +0 -40
  435. data/lua-hooks/ext/lua/ltablib.c +0 -287
  436. data/lua-hooks/ext/lua/ltm.c +0 -75
  437. data/lua-hooks/ext/lua/ltm.h +0 -54
  438. data/lua-hooks/ext/lua/lua.c +0 -392
  439. data/lua-hooks/ext/lua/lua.def +0 -131
  440. data/lua-hooks/ext/lua/lua.rc +0 -28
  441. data/lua-hooks/ext/lua/lua_dll.rc +0 -26
  442. data/lua-hooks/ext/lua/luac.c +0 -200
  443. data/lua-hooks/ext/lua/luac.rc +0 -1
  444. data/lua-hooks/ext/lua/luaconf.h +0 -763
  445. data/lua-hooks/ext/lua/luaconf.h.in +0 -724
  446. data/lua-hooks/ext/lua/luaconf.h.orig +0 -763
  447. data/lua-hooks/ext/lua/lualib.h +0 -53
  448. data/lua-hooks/ext/lua/lundump.c +0 -227
  449. data/lua-hooks/ext/lua/lundump.h +0 -36
  450. data/lua-hooks/ext/lua/lvm.c +0 -767
  451. data/lua-hooks/ext/lua/lvm.h +0 -36
  452. data/lua-hooks/ext/lua/lzio.c +0 -82
  453. data/lua-hooks/ext/lua/lzio.h +0 -67
  454. data/lua-hooks/ext/lua/print.c +0 -227
@@ -0,0 +1,65 @@
1
+ /*
2
+ ** C declaration parser.
3
+ ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
4
+ */
5
+
6
+ #ifndef _LJ_CPARSE_H
7
+ #define _LJ_CPARSE_H
8
+
9
+ #include "lj_obj.h"
10
+ #include "lj_ctype.h"
11
+
12
+ #if LJ_HASFFI
13
+
14
+ /* C parser limits. */
15
+ #define CPARSE_MAX_BUF 32768 /* Max. token buffer size. */
16
+ #define CPARSE_MAX_DECLSTACK 100 /* Max. declaration stack depth. */
17
+ #define CPARSE_MAX_DECLDEPTH 20 /* Max. recursive declaration depth. */
18
+ #define CPARSE_MAX_PACKSTACK 7 /* Max. pack pragma stack depth. */
19
+
20
+ /* Flags for C parser mode. */
21
+ #define CPARSE_MODE_MULTI 1 /* Process multiple declarations. */
22
+ #define CPARSE_MODE_ABSTRACT 2 /* Accept abstract declarators. */
23
+ #define CPARSE_MODE_DIRECT 4 /* Accept direct declarators. */
24
+ #define CPARSE_MODE_FIELD 8 /* Accept field width in bits, too. */
25
+ #define CPARSE_MODE_NOIMPLICIT 16 /* Reject implicit declarations. */
26
+ #define CPARSE_MODE_SKIP 32 /* Skip definitions, ignore errors. */
27
+
28
+ typedef int CPChar; /* C parser character. Unsigned ext. from char. */
29
+ typedef int CPToken; /* C parser token. */
30
+
31
+ /* C parser internal value representation. */
32
+ typedef struct CPValue {
33
+ union {
34
+ int32_t i32; /* Value for CTID_INT32. */
35
+ uint32_t u32; /* Value for CTID_UINT32. */
36
+ };
37
+ CTypeID id; /* C Type ID of the value. */
38
+ } CPValue;
39
+
40
+ /* C parser state. */
41
+ typedef struct CPState {
42
+ CPChar c; /* Current character. */
43
+ CPToken tok; /* Current token. */
44
+ CPValue val; /* Token value. */
45
+ GCstr *str; /* Interned string of identifier/keyword. */
46
+ CType *ct; /* C type table entry. */
47
+ const char *p; /* Current position in input buffer. */
48
+ SBuf sb; /* String buffer for tokens. */
49
+ lua_State *L; /* Lua state. */
50
+ CTState *cts; /* C type state. */
51
+ TValue *param; /* C type parameters. */
52
+ const char *srcname; /* Current source name. */
53
+ BCLine linenumber; /* Input line counter. */
54
+ int depth; /* Recursive declaration depth. */
55
+ uint32_t tmask; /* Type mask for next identifier. */
56
+ uint32_t mode; /* C parser mode. */
57
+ uint8_t packstack[CPARSE_MAX_PACKSTACK]; /* Stack for pack pragmas. */
58
+ uint8_t curpack; /* Current position in pack pragma stack. */
59
+ } CPState;
60
+
61
+ LJ_FUNC int lj_cparse(CPState *cp);
62
+
63
+ #endif
64
+
65
+ #endif
@@ -0,0 +1,1834 @@
1
+ /*
2
+ ** Trace recorder for C data operations.
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 && LJ_HASFFI
12
+
13
+ #include "lj_err.h"
14
+ #include "lj_tab.h"
15
+ #include "lj_frame.h"
16
+ #include "lj_ctype.h"
17
+ #include "lj_cdata.h"
18
+ #include "lj_cparse.h"
19
+ #include "lj_cconv.h"
20
+ #include "lj_carith.h"
21
+ #include "lj_clib.h"
22
+ #include "lj_ccall.h"
23
+ #include "lj_ff.h"
24
+ #include "lj_ir.h"
25
+ #include "lj_jit.h"
26
+ #include "lj_ircall.h"
27
+ #include "lj_iropt.h"
28
+ #include "lj_trace.h"
29
+ #include "lj_record.h"
30
+ #include "lj_ffrecord.h"
31
+ #include "lj_snap.h"
32
+ #include "lj_crecord.h"
33
+ #include "lj_dispatch.h"
34
+ #include "lj_strfmt.h"
35
+
36
+ /* Some local macros to save typing. Undef'd at the end. */
37
+ #define IR(ref) (&J->cur.ir[(ref)])
38
+
39
+ /* Pass IR on to next optimization in chain (FOLD). */
40
+ #define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
41
+
42
+ #define emitconv(a, dt, st, flags) \
43
+ emitir(IRT(IR_CONV, (dt)), (a), (st)|((dt) << 5)|(flags))
44
+
45
+ /* -- C type checks ------------------------------------------------------- */
46
+
47
+ static GCcdata *argv2cdata(jit_State *J, TRef tr, cTValue *o)
48
+ {
49
+ GCcdata *cd;
50
+ TRef trtypeid;
51
+ if (!tref_iscdata(tr))
52
+ lj_trace_err(J, LJ_TRERR_BADTYPE);
53
+ cd = cdataV(o);
54
+ /* Specialize to the CTypeID. */
55
+ trtypeid = emitir(IRT(IR_FLOAD, IRT_U16), tr, IRFL_CDATA_CTYPEID);
56
+ emitir(IRTG(IR_EQ, IRT_INT), trtypeid, lj_ir_kint(J, (int32_t)cd->ctypeid));
57
+ return cd;
58
+ }
59
+
60
+ /* Specialize to the CTypeID held by a cdata constructor. */
61
+ static CTypeID crec_constructor(jit_State *J, GCcdata *cd, TRef tr)
62
+ {
63
+ CTypeID id;
64
+ lua_assert(tref_iscdata(tr) && cd->ctypeid == CTID_CTYPEID);
65
+ id = *(CTypeID *)cdataptr(cd);
66
+ tr = emitir(IRT(IR_FLOAD, IRT_INT), tr, IRFL_CDATA_INT);
67
+ emitir(IRTG(IR_EQ, IRT_INT), tr, lj_ir_kint(J, (int32_t)id));
68
+ return id;
69
+ }
70
+
71
+ static CTypeID argv2ctype(jit_State *J, TRef tr, cTValue *o)
72
+ {
73
+ if (tref_isstr(tr)) {
74
+ GCstr *s = strV(o);
75
+ CPState cp;
76
+ CTypeID oldtop;
77
+ /* Specialize to the string containing the C type declaration. */
78
+ emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, s));
79
+ cp.L = J->L;
80
+ cp.cts = ctype_ctsG(J2G(J));
81
+ oldtop = cp.cts->top;
82
+ cp.srcname = strdata(s);
83
+ cp.p = strdata(s);
84
+ cp.param = NULL;
85
+ cp.mode = CPARSE_MODE_ABSTRACT|CPARSE_MODE_NOIMPLICIT;
86
+ if (lj_cparse(&cp) || cp.cts->top > oldtop) /* Avoid new struct defs. */
87
+ lj_trace_err(J, LJ_TRERR_BADTYPE);
88
+ return cp.val.id;
89
+ } else {
90
+ GCcdata *cd = argv2cdata(J, tr, o);
91
+ return cd->ctypeid == CTID_CTYPEID ? crec_constructor(J, cd, tr) :
92
+ cd->ctypeid;
93
+ }
94
+ }
95
+
96
+ /* Convert CType to IRType (if possible). */
97
+ static IRType crec_ct2irt(CTState *cts, CType *ct)
98
+ {
99
+ if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
100
+ if (LJ_LIKELY(ctype_isnum(ct->info))) {
101
+ if ((ct->info & CTF_FP)) {
102
+ if (ct->size == sizeof(double))
103
+ return IRT_NUM;
104
+ else if (ct->size == sizeof(float))
105
+ return IRT_FLOAT;
106
+ } else {
107
+ uint32_t b = lj_fls(ct->size);
108
+ if (b <= 3)
109
+ return IRT_I8 + 2*b + ((ct->info & CTF_UNSIGNED) ? 1 : 0);
110
+ }
111
+ } else if (ctype_isptr(ct->info)) {
112
+ return (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
113
+ } else if (ctype_iscomplex(ct->info)) {
114
+ if (ct->size == 2*sizeof(double))
115
+ return IRT_NUM;
116
+ else if (ct->size == 2*sizeof(float))
117
+ return IRT_FLOAT;
118
+ }
119
+ return IRT_CDATA;
120
+ }
121
+
122
+ /* -- Optimized memory fill and copy -------------------------------------- */
123
+
124
+ /* Maximum length and unroll of inlined copy/fill. */
125
+ #define CREC_COPY_MAXUNROLL 16
126
+ #define CREC_COPY_MAXLEN 128
127
+
128
+ #define CREC_FILL_MAXUNROLL 16
129
+
130
+ /* Number of windowed registers used for optimized memory copy. */
131
+ #if LJ_TARGET_X86
132
+ #define CREC_COPY_REGWIN 2
133
+ #elif LJ_TARGET_PPC || LJ_TARGET_MIPS
134
+ #define CREC_COPY_REGWIN 8
135
+ #else
136
+ #define CREC_COPY_REGWIN 4
137
+ #endif
138
+
139
+ /* List of memory offsets for copy/fill. */
140
+ typedef struct CRecMemList {
141
+ CTSize ofs; /* Offset in bytes. */
142
+ IRType tp; /* Type of load/store. */
143
+ TRef trofs; /* TRef of interned offset. */
144
+ TRef trval; /* TRef of load value. */
145
+ } CRecMemList;
146
+
147
+ /* Generate copy list for element-wise struct copy. */
148
+ static MSize crec_copy_struct(CRecMemList *ml, CTState *cts, CType *ct)
149
+ {
150
+ CTypeID fid = ct->sib;
151
+ MSize mlp = 0;
152
+ while (fid) {
153
+ CType *df = ctype_get(cts, fid);
154
+ fid = df->sib;
155
+ if (ctype_isfield(df->info)) {
156
+ CType *cct;
157
+ IRType tp;
158
+ if (!gcref(df->name)) continue; /* Ignore unnamed fields. */
159
+ cct = ctype_rawchild(cts, df); /* Field type. */
160
+ tp = crec_ct2irt(cts, cct);
161
+ if (tp == IRT_CDATA) return 0; /* NYI: aggregates. */
162
+ if (mlp >= CREC_COPY_MAXUNROLL) return 0;
163
+ ml[mlp].ofs = df->size;
164
+ ml[mlp].tp = tp;
165
+ mlp++;
166
+ if (ctype_iscomplex(cct->info)) {
167
+ if (mlp >= CREC_COPY_MAXUNROLL) return 0;
168
+ ml[mlp].ofs = df->size + (cct->size >> 1);
169
+ ml[mlp].tp = tp;
170
+ mlp++;
171
+ }
172
+ } else if (!ctype_isconstval(df->info)) {
173
+ /* NYI: bitfields and sub-structures. */
174
+ return 0;
175
+ }
176
+ }
177
+ return mlp;
178
+ }
179
+
180
+ /* Generate unrolled copy list, from highest to lowest step size/alignment. */
181
+ static MSize crec_copy_unroll(CRecMemList *ml, CTSize len, CTSize step,
182
+ IRType tp)
183
+ {
184
+ CTSize ofs = 0;
185
+ MSize mlp = 0;
186
+ if (tp == IRT_CDATA) tp = IRT_U8 + 2*lj_fls(step);
187
+ do {
188
+ while (ofs + step <= len) {
189
+ if (mlp >= CREC_COPY_MAXUNROLL) return 0;
190
+ ml[mlp].ofs = ofs;
191
+ ml[mlp].tp = tp;
192
+ mlp++;
193
+ ofs += step;
194
+ }
195
+ step >>= 1;
196
+ tp -= 2;
197
+ } while (ofs < len);
198
+ return mlp;
199
+ }
200
+
201
+ /*
202
+ ** Emit copy list with windowed loads/stores.
203
+ ** LJ_TARGET_UNALIGNED: may emit unaligned loads/stores (not marked as such).
204
+ */
205
+ static void crec_copy_emit(jit_State *J, CRecMemList *ml, MSize mlp,
206
+ TRef trdst, TRef trsrc)
207
+ {
208
+ MSize i, j, rwin = 0;
209
+ for (i = 0, j = 0; i < mlp; ) {
210
+ TRef trofs = lj_ir_kintp(J, ml[i].ofs);
211
+ TRef trsptr = emitir(IRT(IR_ADD, IRT_PTR), trsrc, trofs);
212
+ ml[i].trval = emitir(IRT(IR_XLOAD, ml[i].tp), trsptr, 0);
213
+ ml[i].trofs = trofs;
214
+ i++;
215
+ rwin += (LJ_SOFTFP && ml[i].tp == IRT_NUM) ? 2 : 1;
216
+ if (rwin >= CREC_COPY_REGWIN || i >= mlp) { /* Flush buffered stores. */
217
+ rwin = 0;
218
+ for ( ; j < i; j++) {
219
+ TRef trdptr = emitir(IRT(IR_ADD, IRT_PTR), trdst, ml[j].trofs);
220
+ emitir(IRT(IR_XSTORE, ml[j].tp), trdptr, ml[j].trval);
221
+ }
222
+ }
223
+ }
224
+ }
225
+
226
+ /* Optimized memory copy. */
227
+ static void crec_copy(jit_State *J, TRef trdst, TRef trsrc, TRef trlen,
228
+ CType *ct)
229
+ {
230
+ if (tref_isk(trlen)) { /* Length must be constant. */
231
+ CRecMemList ml[CREC_COPY_MAXUNROLL];
232
+ MSize mlp = 0;
233
+ CTSize step = 1, len = (CTSize)IR(tref_ref(trlen))->i;
234
+ IRType tp = IRT_CDATA;
235
+ int needxbar = 0;
236
+ if (len == 0) return; /* Shortcut. */
237
+ if (len > CREC_COPY_MAXLEN) goto fallback;
238
+ if (ct) {
239
+ CTState *cts = ctype_ctsG(J2G(J));
240
+ lua_assert(ctype_isarray(ct->info) || ctype_isstruct(ct->info));
241
+ if (ctype_isarray(ct->info)) {
242
+ CType *cct = ctype_rawchild(cts, ct);
243
+ tp = crec_ct2irt(cts, cct);
244
+ if (tp == IRT_CDATA) goto rawcopy;
245
+ step = lj_ir_type_size[tp];
246
+ lua_assert((len & (step-1)) == 0);
247
+ } else if ((ct->info & CTF_UNION)) {
248
+ step = (1u << ctype_align(ct->info));
249
+ goto rawcopy;
250
+ } else {
251
+ mlp = crec_copy_struct(ml, cts, ct);
252
+ goto emitcopy;
253
+ }
254
+ } else {
255
+ rawcopy:
256
+ needxbar = 1;
257
+ if (LJ_TARGET_UNALIGNED || step >= CTSIZE_PTR)
258
+ step = CTSIZE_PTR;
259
+ }
260
+ mlp = crec_copy_unroll(ml, len, step, tp);
261
+ emitcopy:
262
+ if (mlp) {
263
+ crec_copy_emit(J, ml, mlp, trdst, trsrc);
264
+ if (needxbar)
265
+ emitir(IRT(IR_XBAR, IRT_NIL), 0, 0);
266
+ return;
267
+ }
268
+ }
269
+ fallback:
270
+ /* Call memcpy. Always needs a barrier to disable alias analysis. */
271
+ lj_ir_call(J, IRCALL_memcpy, trdst, trsrc, trlen);
272
+ emitir(IRT(IR_XBAR, IRT_NIL), 0, 0);
273
+ }
274
+
275
+ /* Generate unrolled fill list, from highest to lowest step size/alignment. */
276
+ static MSize crec_fill_unroll(CRecMemList *ml, CTSize len, CTSize step)
277
+ {
278
+ CTSize ofs = 0;
279
+ MSize mlp = 0;
280
+ IRType tp = IRT_U8 + 2*lj_fls(step);
281
+ do {
282
+ while (ofs + step <= len) {
283
+ if (mlp >= CREC_COPY_MAXUNROLL) return 0;
284
+ ml[mlp].ofs = ofs;
285
+ ml[mlp].tp = tp;
286
+ mlp++;
287
+ ofs += step;
288
+ }
289
+ step >>= 1;
290
+ tp -= 2;
291
+ } while (ofs < len);
292
+ return mlp;
293
+ }
294
+
295
+ /*
296
+ ** Emit stores for fill list.
297
+ ** LJ_TARGET_UNALIGNED: may emit unaligned stores (not marked as such).
298
+ */
299
+ static void crec_fill_emit(jit_State *J, CRecMemList *ml, MSize mlp,
300
+ TRef trdst, TRef trfill)
301
+ {
302
+ MSize i;
303
+ for (i = 0; i < mlp; i++) {
304
+ TRef trofs = lj_ir_kintp(J, ml[i].ofs);
305
+ TRef trdptr = emitir(IRT(IR_ADD, IRT_PTR), trdst, trofs);
306
+ emitir(IRT(IR_XSTORE, ml[i].tp), trdptr, trfill);
307
+ }
308
+ }
309
+
310
+ /* Optimized memory fill. */
311
+ static void crec_fill(jit_State *J, TRef trdst, TRef trlen, TRef trfill,
312
+ CTSize step)
313
+ {
314
+ if (tref_isk(trlen)) { /* Length must be constant. */
315
+ CRecMemList ml[CREC_FILL_MAXUNROLL];
316
+ MSize mlp;
317
+ CTSize len = (CTSize)IR(tref_ref(trlen))->i;
318
+ if (len == 0) return; /* Shortcut. */
319
+ if (LJ_TARGET_UNALIGNED || step >= CTSIZE_PTR)
320
+ step = CTSIZE_PTR;
321
+ if (step * CREC_FILL_MAXUNROLL < len) goto fallback;
322
+ mlp = crec_fill_unroll(ml, len, step);
323
+ if (!mlp) goto fallback;
324
+ if (tref_isk(trfill) || ml[0].tp != IRT_U8)
325
+ trfill = emitconv(trfill, IRT_INT, IRT_U8, 0);
326
+ if (ml[0].tp != IRT_U8) { /* Scatter U8 to U16/U32/U64. */
327
+ if (CTSIZE_PTR == 8 && ml[0].tp == IRT_U64) {
328
+ if (tref_isk(trfill)) /* Pointless on x64 with zero-extended regs. */
329
+ trfill = emitconv(trfill, IRT_U64, IRT_U32, 0);
330
+ trfill = emitir(IRT(IR_MUL, IRT_U64), trfill,
331
+ lj_ir_kint64(J, U64x(01010101,01010101)));
332
+ } else {
333
+ trfill = emitir(IRTI(IR_MUL), trfill,
334
+ lj_ir_kint(J, ml[0].tp == IRT_U16 ? 0x0101 : 0x01010101));
335
+ }
336
+ }
337
+ crec_fill_emit(J, ml, mlp, trdst, trfill);
338
+ } else {
339
+ fallback:
340
+ /* Call memset. Always needs a barrier to disable alias analysis. */
341
+ lj_ir_call(J, IRCALL_memset, trdst, trfill, trlen); /* Note: arg order! */
342
+ }
343
+ emitir(IRT(IR_XBAR, IRT_NIL), 0, 0);
344
+ }
345
+
346
+ /* -- Convert C type to C type -------------------------------------------- */
347
+
348
+ /*
349
+ ** This code mirrors the code in lj_cconv.c. It performs the same steps
350
+ ** for the trace recorder that lj_cconv.c does for the interpreter.
351
+ **
352
+ ** One major difference is that we can get away with much fewer checks
353
+ ** here. E.g. checks for casts, constness or correct types can often be
354
+ ** omitted, even if they might fail. The interpreter subsequently throws
355
+ ** an error, which aborts the trace.
356
+ **
357
+ ** All operations are specialized to their C types, so the on-trace
358
+ ** outcome must be the same as the outcome in the interpreter. If the
359
+ ** interpreter doesn't throw an error, then the trace is correct, too.
360
+ ** Care must be taken not to generate invalid (temporary) IR or to
361
+ ** trigger asserts.
362
+ */
363
+
364
+ /* Determine whether a passed number or cdata number is non-zero. */
365
+ static int crec_isnonzero(CType *s, void *p)
366
+ {
367
+ if (p == (void *)0)
368
+ return 0;
369
+ if (p == (void *)1)
370
+ return 1;
371
+ if ((s->info & CTF_FP)) {
372
+ if (s->size == sizeof(float))
373
+ return (*(float *)p != 0);
374
+ else
375
+ return (*(double *)p != 0);
376
+ } else {
377
+ if (s->size == 1)
378
+ return (*(uint8_t *)p != 0);
379
+ else if (s->size == 2)
380
+ return (*(uint16_t *)p != 0);
381
+ else if (s->size == 4)
382
+ return (*(uint32_t *)p != 0);
383
+ else
384
+ return (*(uint64_t *)p != 0);
385
+ }
386
+ }
387
+
388
+ static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
389
+ void *svisnz)
390
+ {
391
+ IRType dt = crec_ct2irt(ctype_ctsG(J2G(J)), d);
392
+ IRType st = crec_ct2irt(ctype_ctsG(J2G(J)), s);
393
+ CTSize dsize = d->size, ssize = s->size;
394
+ CTInfo dinfo = d->info, sinfo = s->info;
395
+
396
+ if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT)
397
+ goto err_conv;
398
+
399
+ /*
400
+ ** Note: Unlike lj_cconv_ct_ct(), sp holds the _value_ of pointers and
401
+ ** numbers up to 8 bytes. Otherwise sp holds a pointer.
402
+ */
403
+
404
+ switch (cconv_idx2(dinfo, sinfo)) {
405
+ /* Destination is a bool. */
406
+ case CCX(B, B):
407
+ goto xstore; /* Source operand is already normalized. */
408
+ case CCX(B, I):
409
+ case CCX(B, F):
410
+ if (st != IRT_CDATA) {
411
+ /* Specialize to the result of a comparison against 0. */
412
+ TRef zero = (st == IRT_NUM || st == IRT_FLOAT) ? lj_ir_knum(J, 0) :
413
+ (st == IRT_I64 || st == IRT_U64) ? lj_ir_kint64(J, 0) :
414
+ lj_ir_kint(J, 0);
415
+ int isnz = crec_isnonzero(s, svisnz);
416
+ emitir(IRTG(isnz ? IR_NE : IR_EQ, st), sp, zero);
417
+ sp = lj_ir_kint(J, isnz);
418
+ goto xstore;
419
+ }
420
+ goto err_nyi;
421
+
422
+ /* Destination is an integer. */
423
+ case CCX(I, B):
424
+ case CCX(I, I):
425
+ conv_I_I:
426
+ if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
427
+ /* Extend 32 to 64 bit integer. */
428
+ if (dsize == 8 && ssize < 8 && !(LJ_64 && (sinfo & CTF_UNSIGNED)))
429
+ sp = emitconv(sp, dt, ssize < 4 ? IRT_INT : st,
430
+ (sinfo & CTF_UNSIGNED) ? 0 : IRCONV_SEXT);
431
+ else if (dsize < 8 && ssize == 8) /* Truncate from 64 bit integer. */
432
+ sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, 0);
433
+ else if (st == IRT_INT)
434
+ sp = lj_opt_narrow_toint(J, sp);
435
+ xstore:
436
+ if (dt == IRT_I64 || dt == IRT_U64) lj_needsplit(J);
437
+ if (dp == 0) return sp;
438
+ emitir(IRT(IR_XSTORE, dt), dp, sp);
439
+ break;
440
+ case CCX(I, C):
441
+ sp = emitir(IRT(IR_XLOAD, st), sp, 0); /* Load re. */
442
+ /* fallthrough */
443
+ case CCX(I, F):
444
+ if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
445
+ sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, IRCONV_ANY);
446
+ goto xstore;
447
+ case CCX(I, P):
448
+ case CCX(I, A):
449
+ sinfo = CTINFO(CT_NUM, CTF_UNSIGNED);
450
+ ssize = CTSIZE_PTR;
451
+ st = IRT_UINTP;
452
+ if (((dsize ^ ssize) & 8) == 0) { /* Must insert no-op type conversion. */
453
+ sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, IRT_PTR, 0);
454
+ goto xstore;
455
+ }
456
+ goto conv_I_I;
457
+
458
+ /* Destination is a floating-point number. */
459
+ case CCX(F, B):
460
+ case CCX(F, I):
461
+ conv_F_I:
462
+ if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
463
+ sp = emitconv(sp, dt, ssize < 4 ? IRT_INT : st, 0);
464
+ goto xstore;
465
+ case CCX(F, C):
466
+ sp = emitir(IRT(IR_XLOAD, st), sp, 0); /* Load re. */
467
+ /* fallthrough */
468
+ case CCX(F, F):
469
+ conv_F_F:
470
+ if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
471
+ if (dt != st) sp = emitconv(sp, dt, st, 0);
472
+ goto xstore;
473
+
474
+ /* Destination is a complex number. */
475
+ case CCX(C, I):
476
+ case CCX(C, F):
477
+ { /* Clear im. */
478
+ TRef ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, (dsize >> 1)));
479
+ emitir(IRT(IR_XSTORE, dt), ptr, lj_ir_knum(J, 0));
480
+ }
481
+ /* Convert to re. */
482
+ if ((sinfo & CTF_FP)) goto conv_F_F; else goto conv_F_I;
483
+
484
+ case CCX(C, C):
485
+ if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
486
+ {
487
+ TRef re, im, ptr;
488
+ re = emitir(IRT(IR_XLOAD, st), sp, 0);
489
+ ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, (ssize >> 1)));
490
+ im = emitir(IRT(IR_XLOAD, st), ptr, 0);
491
+ if (dt != st) {
492
+ re = emitconv(re, dt, st, 0);
493
+ im = emitconv(im, dt, st, 0);
494
+ }
495
+ emitir(IRT(IR_XSTORE, dt), dp, re);
496
+ ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, (dsize >> 1)));
497
+ emitir(IRT(IR_XSTORE, dt), ptr, im);
498
+ }
499
+ break;
500
+
501
+ /* Destination is a vector. */
502
+ case CCX(V, I):
503
+ case CCX(V, F):
504
+ case CCX(V, C):
505
+ case CCX(V, V):
506
+ goto err_nyi;
507
+
508
+ /* Destination is a pointer. */
509
+ case CCX(P, P):
510
+ case CCX(P, A):
511
+ case CCX(P, S):
512
+ /* There are only 32 bit pointers/addresses on 32 bit machines.
513
+ ** Also ok on x64, since all 32 bit ops clear the upper part of the reg.
514
+ */
515
+ goto xstore;
516
+ case CCX(P, I):
517
+ if (st == IRT_CDATA) goto err_nyi;
518
+ if (!LJ_64 && ssize == 8) /* Truncate from 64 bit integer. */
519
+ sp = emitconv(sp, IRT_U32, st, 0);
520
+ goto xstore;
521
+ case CCX(P, F):
522
+ if (st == IRT_CDATA) goto err_nyi;
523
+ /* The signed conversion is cheaper. x64 really has 47 bit pointers. */
524
+ sp = emitconv(sp, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32,
525
+ st, IRCONV_ANY);
526
+ goto xstore;
527
+
528
+ /* Destination is an array. */
529
+ case CCX(A, A):
530
+ /* Destination is a struct/union. */
531
+ case CCX(S, S):
532
+ if (dp == 0) goto err_conv;
533
+ crec_copy(J, dp, sp, lj_ir_kint(J, dsize), d);
534
+ break;
535
+
536
+ default:
537
+ err_conv:
538
+ err_nyi:
539
+ lj_trace_err(J, LJ_TRERR_NYICONV);
540
+ break;
541
+ }
542
+ return 0;
543
+ }
544
+
545
+ /* -- Convert C type to TValue (load) ------------------------------------- */
546
+
547
+ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
548
+ {
549
+ CTState *cts = ctype_ctsG(J2G(J));
550
+ IRType t = crec_ct2irt(cts, s);
551
+ CTInfo sinfo = s->info;
552
+ if (ctype_isnum(sinfo)) {
553
+ TRef tr;
554
+ if (t == IRT_CDATA)
555
+ goto err_nyi; /* NYI: copyval of >64 bit integers. */
556
+ tr = emitir(IRT(IR_XLOAD, t), sp, 0);
557
+ if (t == IRT_FLOAT || t == IRT_U32) { /* Keep uint32_t/float as numbers. */
558
+ return emitconv(tr, IRT_NUM, t, 0);
559
+ } else if (t == IRT_I64 || t == IRT_U64) { /* Box 64 bit integer. */
560
+ sp = tr;
561
+ lj_needsplit(J);
562
+ } else if ((sinfo & CTF_BOOL)) {
563
+ /* Assume not equal to zero. Fixup and emit pending guard later. */
564
+ lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0));
565
+ J->postproc = LJ_POST_FIXGUARD;
566
+ return TREF_TRUE;
567
+ } else {
568
+ return tr;
569
+ }
570
+ } else if (ctype_isptr(sinfo) || ctype_isenum(sinfo)) {
571
+ sp = emitir(IRT(IR_XLOAD, t), sp, 0); /* Box pointers and enums. */
572
+ } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) {
573
+ cts->L = J->L;
574
+ sid = lj_ctype_intern(cts, CTINFO_REF(sid), CTSIZE_PTR); /* Create ref. */
575
+ } else if (ctype_iscomplex(sinfo)) { /* Unbox/box complex. */
576
+ ptrdiff_t esz = (ptrdiff_t)(s->size >> 1);
577
+ TRef ptr, tr1, tr2, dp;
578
+ dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL);
579
+ tr1 = emitir(IRT(IR_XLOAD, t), sp, 0);
580
+ ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, esz));
581
+ tr2 = emitir(IRT(IR_XLOAD, t), ptr, 0);
582
+ ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, sizeof(GCcdata)));
583
+ emitir(IRT(IR_XSTORE, t), ptr, tr1);
584
+ ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, sizeof(GCcdata)+esz));
585
+ emitir(IRT(IR_XSTORE, t), ptr, tr2);
586
+ return dp;
587
+ } else {
588
+ /* NYI: copyval of vectors. */
589
+ err_nyi:
590
+ lj_trace_err(J, LJ_TRERR_NYICONV);
591
+ }
592
+ /* Box pointer, ref, enum or 64 bit integer. */
593
+ return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, sid), sp);
594
+ }
595
+
596
+ /* -- Convert TValue to C type (store) ------------------------------------ */
597
+
598
+ static TRef crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, cTValue *sval)
599
+ {
600
+ CTState *cts = ctype_ctsG(J2G(J));
601
+ CTypeID sid = CTID_P_VOID;
602
+ void *svisnz = 0;
603
+ CType *s;
604
+ if (LJ_LIKELY(tref_isinteger(sp))) {
605
+ sid = CTID_INT32;
606
+ svisnz = (void *)(intptr_t)(tvisint(sval)?(intV(sval)!=0):!tviszero(sval));
607
+ } else if (tref_isnum(sp)) {
608
+ sid = CTID_DOUBLE;
609
+ svisnz = (void *)(intptr_t)(tvisint(sval)?(intV(sval)!=0):!tviszero(sval));
610
+ } else if (tref_isbool(sp)) {
611
+ sp = lj_ir_kint(J, tref_istrue(sp) ? 1 : 0);
612
+ sid = CTID_BOOL;
613
+ } else if (tref_isnil(sp)) {
614
+ sp = lj_ir_kptr(J, NULL);
615
+ } else if (tref_isudata(sp)) {
616
+ GCudata *ud = udataV(sval);
617
+ if (ud->udtype == UDTYPE_IO_FILE) {
618
+ TRef tr = emitir(IRT(IR_FLOAD, IRT_U8), sp, IRFL_UDATA_UDTYPE);
619
+ emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, UDTYPE_IO_FILE));
620
+ sp = emitir(IRT(IR_FLOAD, IRT_PTR), sp, IRFL_UDATA_FILE);
621
+ } else {
622
+ sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCudata)));
623
+ }
624
+ } else if (tref_isstr(sp)) {
625
+ if (ctype_isenum(d->info)) { /* Match string against enum constant. */
626
+ GCstr *str = strV(sval);
627
+ CTSize ofs;
628
+ CType *cct = lj_ctype_getfield(cts, d, str, &ofs);
629
+ /* Specialize to the name of the enum constant. */
630
+ emitir(IRTG(IR_EQ, IRT_STR), sp, lj_ir_kstr(J, str));
631
+ if (cct && ctype_isconstval(cct->info)) {
632
+ lua_assert(ctype_child(cts, cct)->size == 4);
633
+ svisnz = (void *)(intptr_t)(ofs != 0);
634
+ sp = lj_ir_kint(J, (int32_t)ofs);
635
+ sid = ctype_cid(cct->info);
636
+ } /* else: interpreter will throw. */
637
+ } else if (ctype_isrefarray(d->info)) { /* Copy string to array. */
638
+ lj_trace_err(J, LJ_TRERR_BADTYPE); /* NYI */
639
+ } else { /* Otherwise pass the string data as a const char[]. */
640
+ /* Don't use STRREF. It folds with SNEW, which loses the trailing NUL. */
641
+ sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCstr)));
642
+ sid = CTID_A_CCHAR;
643
+ }
644
+ } else if (tref_islightud(sp)) {
645
+ #if LJ_64
646
+ sp = emitir(IRT(IR_BAND, IRT_P64), sp,
647
+ lj_ir_kint64(J, U64x(00007fff,ffffffff)));
648
+ #endif
649
+ } else { /* NYI: tref_istab(sp). */
650
+ IRType t;
651
+ sid = argv2cdata(J, sp, sval)->ctypeid;
652
+ s = ctype_raw(cts, sid);
653
+ svisnz = cdataptr(cdataV(sval));
654
+ if (ctype_isfunc(s->info)) {
655
+ sid = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|sid), CTSIZE_PTR);
656
+ s = ctype_get(cts, sid);
657
+ t = IRT_PTR;
658
+ } else {
659
+ t = crec_ct2irt(cts, s);
660
+ }
661
+ if (ctype_isptr(s->info)) {
662
+ sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR);
663
+ if (ctype_isref(s->info)) {
664
+ svisnz = *(void **)svisnz;
665
+ s = ctype_rawchild(cts, s);
666
+ if (ctype_isenum(s->info)) s = ctype_child(cts, s);
667
+ t = crec_ct2irt(cts, s);
668
+ } else {
669
+ goto doconv;
670
+ }
671
+ } else if (t == IRT_I64 || t == IRT_U64) {
672
+ sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_INT64);
673
+ lj_needsplit(J);
674
+ goto doconv;
675
+ } else if (t == IRT_INT || t == IRT_U32) {
676
+ if (ctype_isenum(s->info)) s = ctype_child(cts, s);
677
+ sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_INT);
678
+ goto doconv;
679
+ } else {
680
+ sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCcdata)));
681
+ }
682
+ if (ctype_isnum(s->info) && t != IRT_CDATA)
683
+ sp = emitir(IRT(IR_XLOAD, t), sp, 0); /* Load number value. */
684
+ goto doconv;
685
+ }
686
+ s = ctype_get(cts, sid);
687
+ doconv:
688
+ if (ctype_isenum(d->info)) d = ctype_child(cts, d);
689
+ return crec_ct_ct(J, d, s, dp, sp, svisnz);
690
+ }
691
+
692
+ /* -- C data metamethods -------------------------------------------------- */
693
+
694
+ /* This would be rather difficult in FOLD, so do it here:
695
+ ** (base+k)+(idx*sz)+ofs ==> (base+idx*sz)+(ofs+k)
696
+ ** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz)
697
+ */
698
+ static TRef crec_reassoc_ofs(jit_State *J, TRef tr, ptrdiff_t *ofsp, MSize sz)
699
+ {
700
+ IRIns *ir = IR(tref_ref(tr));
701
+ if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && irref_isk(ir->op2) &&
702
+ (ir->o == IR_ADD || ir->o == IR_ADDOV || ir->o == IR_SUBOV)) {
703
+ IRIns *irk = IR(ir->op2);
704
+ ptrdiff_t k;
705
+ if (LJ_64 && irk->o == IR_KINT64)
706
+ k = (ptrdiff_t)ir_kint64(irk)->u64 * sz;
707
+ else
708
+ k = (ptrdiff_t)irk->i * sz;
709
+ if (ir->o == IR_SUBOV) *ofsp -= k; else *ofsp += k;
710
+ tr = ir->op1; /* Not a TRef, but the caller doesn't care. */
711
+ }
712
+ return tr;
713
+ }
714
+
715
+ /* Record ctype __index/__newindex metamethods. */
716
+ static void crec_index_meta(jit_State *J, CTState *cts, CType *ct,
717
+ RecordFFData *rd)
718
+ {
719
+ CTypeID id = ctype_typeid(cts, ct);
720
+ cTValue *tv = lj_ctype_meta(cts, id, rd->data ? MM_newindex : MM_index);
721
+ if (!tv)
722
+ lj_trace_err(J, LJ_TRERR_BADTYPE);
723
+ if (tvisfunc(tv)) {
724
+ J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME;
725
+ rd->nres = -1; /* Pending tailcall. */
726
+ } else if (rd->data == 0 && tvistab(tv) && tref_isstr(J->base[1])) {
727
+ /* Specialize to result of __index lookup. */
728
+ cTValue *o = lj_tab_get(J->L, tabV(tv), &rd->argv[1]);
729
+ J->base[0] = lj_record_constify(J, o);
730
+ if (!J->base[0])
731
+ lj_trace_err(J, LJ_TRERR_BADTYPE);
732
+ /* Always specialize to the key. */
733
+ emitir(IRTG(IR_EQ, IRT_STR), J->base[1], lj_ir_kstr(J, strV(&rd->argv[1])));
734
+ } else {
735
+ /* NYI: resolving of non-function metamethods. */
736
+ /* NYI: non-string keys for __index table. */
737
+ /* NYI: stores to __newindex table. */
738
+ lj_trace_err(J, LJ_TRERR_BADTYPE);
739
+ }
740
+ }
741
+
742
+ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd)
743
+ {
744
+ TRef idx, ptr = J->base[0];
745
+ ptrdiff_t ofs = sizeof(GCcdata);
746
+ GCcdata *cd = argv2cdata(J, ptr, &rd->argv[0]);
747
+ CTState *cts = ctype_ctsG(J2G(J));
748
+ CType *ct = ctype_raw(cts, cd->ctypeid);
749
+ CTypeID sid = 0;
750
+
751
+ /* Resolve pointer or reference for cdata object. */
752
+ if (ctype_isptr(ct->info)) {
753
+ IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
754
+ if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct);
755
+ ptr = emitir(IRT(IR_FLOAD, t), ptr, IRFL_CDATA_PTR);
756
+ ofs = 0;
757
+ ptr = crec_reassoc_ofs(J, ptr, &ofs, 1);
758
+ }
759
+
760
+ again:
761
+ idx = J->base[1];
762
+ if (tref_isnumber(idx)) {
763
+ idx = lj_opt_narrow_cindex(J, idx);
764
+ if (ctype_ispointer(ct->info)) {
765
+ CTSize sz;
766
+ integer_key:
767
+ if ((ct->info & CTF_COMPLEX))
768
+ idx = emitir(IRT(IR_BAND, IRT_INTP), idx, lj_ir_kintp(J, 1));
769
+ sz = lj_ctype_size(cts, (sid = ctype_cid(ct->info)));
770
+ idx = crec_reassoc_ofs(J, idx, &ofs, sz);
771
+ #if LJ_TARGET_ARM || LJ_TARGET_PPC
772
+ /* Hoist base add to allow fusion of index/shift into operands. */
773
+ if (LJ_LIKELY(J->flags & JIT_F_OPT_LOOP) && ofs
774
+ #if LJ_TARGET_ARM
775
+ && (sz == 1 || sz == 4)
776
+ #endif
777
+ ) {
778
+ ptr = emitir(IRT(IR_ADD, IRT_PTR), ptr, lj_ir_kintp(J, ofs));
779
+ ofs = 0;
780
+ }
781
+ #endif
782
+ idx = emitir(IRT(IR_MUL, IRT_INTP), idx, lj_ir_kintp(J, sz));
783
+ ptr = emitir(IRT(IR_ADD, IRT_PTR), idx, ptr);
784
+ }
785
+ } else if (tref_iscdata(idx)) {
786
+ GCcdata *cdk = cdataV(&rd->argv[1]);
787
+ CType *ctk = ctype_raw(cts, cdk->ctypeid);
788
+ IRType t = crec_ct2irt(cts, ctk);
789
+ if (ctype_ispointer(ct->info) && t >= IRT_I8 && t <= IRT_U64) {
790
+ if (ctk->size == 8) {
791
+ idx = emitir(IRT(IR_FLOAD, t), idx, IRFL_CDATA_INT64);
792
+ } else if (ctk->size == 4) {
793
+ idx = emitir(IRT(IR_FLOAD, t), idx, IRFL_CDATA_INT);
794
+ } else {
795
+ idx = emitir(IRT(IR_ADD, IRT_PTR), idx,
796
+ lj_ir_kintp(J, sizeof(GCcdata)));
797
+ idx = emitir(IRT(IR_XLOAD, t), idx, 0);
798
+ }
799
+ if (LJ_64 && ctk->size < sizeof(intptr_t) && !(ctk->info & CTF_UNSIGNED))
800
+ idx = emitconv(idx, IRT_INTP, IRT_INT, IRCONV_SEXT);
801
+ if (!LJ_64 && ctk->size > sizeof(intptr_t)) {
802
+ idx = emitconv(idx, IRT_INTP, t, 0);
803
+ lj_needsplit(J);
804
+ }
805
+ goto integer_key;
806
+ }
807
+ } else if (tref_isstr(idx)) {
808
+ GCstr *name = strV(&rd->argv[1]);
809
+ if (cd && cd->ctypeid == CTID_CTYPEID)
810
+ ct = ctype_raw(cts, crec_constructor(J, cd, ptr));
811
+ if (ctype_isstruct(ct->info)) {
812
+ CTSize fofs;
813
+ CType *fct;
814
+ fct = lj_ctype_getfield(cts, ct, name, &fofs);
815
+ if (fct) {
816
+ /* Always specialize to the field name. */
817
+ emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name));
818
+ if (ctype_isconstval(fct->info)) {
819
+ if (fct->size >= 0x80000000u &&
820
+ (ctype_child(cts, fct)->info & CTF_UNSIGNED)) {
821
+ J->base[0] = lj_ir_knum(J, (lua_Number)(uint32_t)fct->size);
822
+ return;
823
+ }
824
+ J->base[0] = lj_ir_kint(J, (int32_t)fct->size);
825
+ return; /* Interpreter will throw for newindex. */
826
+ } else if (ctype_isbitfield(fct->info)) {
827
+ lj_trace_err(J, LJ_TRERR_NYICONV);
828
+ } else {
829
+ lua_assert(ctype_isfield(fct->info));
830
+ sid = ctype_cid(fct->info);
831
+ }
832
+ ofs += (ptrdiff_t)fofs;
833
+ }
834
+ } else if (ctype_iscomplex(ct->info)) {
835
+ if (name->len == 2 &&
836
+ ((strdata(name)[0] == 'r' && strdata(name)[1] == 'e') ||
837
+ (strdata(name)[0] == 'i' && strdata(name)[1] == 'm'))) {
838
+ /* Always specialize to the field name. */
839
+ emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name));
840
+ if (strdata(name)[0] == 'i') ofs += (ct->size >> 1);
841
+ sid = ctype_cid(ct->info);
842
+ }
843
+ }
844
+ }
845
+ if (!sid) {
846
+ if (ctype_isptr(ct->info)) { /* Automatically perform '->'. */
847
+ CType *cct = ctype_rawchild(cts, ct);
848
+ if (ctype_isstruct(cct->info)) {
849
+ ct = cct;
850
+ cd = NULL;
851
+ if (tref_isstr(idx)) goto again;
852
+ }
853
+ }
854
+ crec_index_meta(J, cts, ct, rd);
855
+ return;
856
+ }
857
+
858
+ if (ofs)
859
+ ptr = emitir(IRT(IR_ADD, IRT_PTR), ptr, lj_ir_kintp(J, ofs));
860
+
861
+ /* Resolve reference for field. */
862
+ ct = ctype_get(cts, sid);
863
+ if (ctype_isref(ct->info)) {
864
+ ptr = emitir(IRT(IR_XLOAD, IRT_PTR), ptr, 0);
865
+ sid = ctype_cid(ct->info);
866
+ ct = ctype_get(cts, sid);
867
+ }
868
+
869
+ while (ctype_isattrib(ct->info))
870
+ ct = ctype_child(cts, ct); /* Skip attributes. */
871
+
872
+ if (rd->data == 0) { /* __index metamethod. */
873
+ J->base[0] = crec_tv_ct(J, ct, sid, ptr);
874
+ } else { /* __newindex metamethod. */
875
+ rd->nres = 0;
876
+ J->needsnap = 1;
877
+ crec_ct_tv(J, ct, ptr, J->base[2], &rd->argv[2]);
878
+ }
879
+ }
880
+
881
+ /* Record setting a finalizer. */
882
+ static void crec_finalizer(jit_State *J, TRef trcd, TRef trfin, cTValue *fin)
883
+ {
884
+ if (tvisgcv(fin)) {
885
+ if (!trfin) trfin = lj_ir_kptr(J, gcval(fin));
886
+ } else if (tvisnil(fin)) {
887
+ trfin = lj_ir_kptr(J, NULL);
888
+ } else {
889
+ lj_trace_err(J, LJ_TRERR_BADTYPE);
890
+ }
891
+ lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd,
892
+ trfin, lj_ir_kint(J, (int32_t)itype(fin)));
893
+ J->needsnap = 1;
894
+ }
895
+
896
+ /* Record cdata allocation. */
897
+ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
898
+ {
899
+ CTState *cts = ctype_ctsG(J2G(J));
900
+ CTSize sz;
901
+ CTInfo info = lj_ctype_info(cts, id, &sz);
902
+ CType *d = ctype_raw(cts, id);
903
+ TRef trcd, trid = lj_ir_kint(J, id);
904
+ cTValue *fin;
905
+ /* Use special instruction to box pointer or 32/64 bit integer. */
906
+ if (ctype_isptr(info) || (ctype_isinteger(info) && (sz == 4 || sz == 8))) {
907
+ TRef sp = J->base[1] ? crec_ct_tv(J, d, 0, J->base[1], &rd->argv[1]) :
908
+ ctype_isptr(info) ? lj_ir_kptr(J, NULL) :
909
+ sz == 4 ? lj_ir_kint(J, 0) :
910
+ (lj_needsplit(J), lj_ir_kint64(J, 0));
911
+ J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, sp);
912
+ return;
913
+ } else {
914
+ TRef trsz = TREF_NIL;
915
+ if ((info & CTF_VLA)) { /* Calculate VLA/VLS size at runtime. */
916
+ CTSize sz0, sz1;
917
+ if (!J->base[1] || J->base[2])
918
+ lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init VLA/VLS. */
919
+ trsz = crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0,
920
+ J->base[1], &rd->argv[1]);
921
+ sz0 = lj_ctype_vlsize(cts, d, 0);
922
+ sz1 = lj_ctype_vlsize(cts, d, 1);
923
+ trsz = emitir(IRTGI(IR_MULOV), trsz, lj_ir_kint(J, (int32_t)(sz1-sz0)));
924
+ trsz = emitir(IRTGI(IR_ADDOV), trsz, lj_ir_kint(J, (int32_t)sz0));
925
+ J->base[1] = 0; /* Simplify logic below. */
926
+ } else if (ctype_align(info) > CT_MEMALIGN) {
927
+ trsz = lj_ir_kint(J, sz);
928
+ }
929
+ trcd = emitir(IRTG(IR_CNEW, IRT_CDATA), trid, trsz);
930
+ if (sz > 128 || (info & CTF_VLA)) {
931
+ TRef dp;
932
+ CTSize align;
933
+ special: /* Only handle bulk zero-fill for large/VLA/VLS types. */
934
+ if (J->base[1])
935
+ lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init large/VLA/VLS types. */
936
+ dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, lj_ir_kintp(J, sizeof(GCcdata)));
937
+ if (trsz == TREF_NIL) trsz = lj_ir_kint(J, sz);
938
+ align = ctype_align(info);
939
+ if (align < CT_MEMALIGN) align = CT_MEMALIGN;
940
+ crec_fill(J, dp, trsz, lj_ir_kint(J, 0), (1u << align));
941
+ } else if (J->base[1] && !J->base[2] &&
942
+ !lj_cconv_multi_init(cts, d, &rd->argv[1])) {
943
+ goto single_init;
944
+ } else if (ctype_isarray(d->info)) {
945
+ CType *dc = ctype_rawchild(cts, d); /* Array element type. */
946
+ CTSize ofs, esize = dc->size;
947
+ TRef sp = 0;
948
+ TValue tv;
949
+ TValue *sval = &tv;
950
+ MSize i;
951
+ tv.u64 = 0;
952
+ if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info)) ||
953
+ esize * CREC_FILL_MAXUNROLL < sz)
954
+ goto special;
955
+ for (i = 1, ofs = 0; ofs < sz; ofs += esize) {
956
+ TRef dp = emitir(IRT(IR_ADD, IRT_PTR), trcd,
957
+ lj_ir_kintp(J, ofs + sizeof(GCcdata)));
958
+ if (J->base[i]) {
959
+ sp = J->base[i];
960
+ sval = &rd->argv[i];
961
+ i++;
962
+ } else if (i != 2) {
963
+ sp = ctype_isnum(dc->info) ? lj_ir_kint(J, 0) : TREF_NIL;
964
+ }
965
+ crec_ct_tv(J, dc, dp, sp, sval);
966
+ }
967
+ } else if (ctype_isstruct(d->info)) {
968
+ CTypeID fid = d->sib;
969
+ MSize i = 1;
970
+ while (fid) {
971
+ CType *df = ctype_get(cts, fid);
972
+ fid = df->sib;
973
+ if (ctype_isfield(df->info)) {
974
+ CType *dc;
975
+ TRef sp, dp;
976
+ TValue tv;
977
+ TValue *sval = &tv;
978
+ setintV(&tv, 0);
979
+ if (!gcref(df->name)) continue; /* Ignore unnamed fields. */
980
+ dc = ctype_rawchild(cts, df); /* Field type. */
981
+ if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info) ||
982
+ ctype_isenum(dc->info)))
983
+ lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init aggregates. */
984
+ if (J->base[i]) {
985
+ sp = J->base[i];
986
+ sval = &rd->argv[i];
987
+ i++;
988
+ } else {
989
+ sp = ctype_isptr(dc->info) ? TREF_NIL : lj_ir_kint(J, 0);
990
+ }
991
+ dp = emitir(IRT(IR_ADD, IRT_PTR), trcd,
992
+ lj_ir_kintp(J, df->size + sizeof(GCcdata)));
993
+ crec_ct_tv(J, dc, dp, sp, sval);
994
+ } else if (!ctype_isconstval(df->info)) {
995
+ /* NYI: init bitfields and sub-structures. */
996
+ lj_trace_err(J, LJ_TRERR_NYICONV);
997
+ }
998
+ }
999
+ } else {
1000
+ TRef dp;
1001
+ single_init:
1002
+ dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, lj_ir_kintp(J, sizeof(GCcdata)));
1003
+ if (J->base[1]) {
1004
+ crec_ct_tv(J, d, dp, J->base[1], &rd->argv[1]);
1005
+ } else {
1006
+ TValue tv;
1007
+ tv.u64 = 0;
1008
+ crec_ct_tv(J, d, dp, lj_ir_kint(J, 0), &tv);
1009
+ }
1010
+ }
1011
+ }
1012
+ J->base[0] = trcd;
1013
+ /* Handle __gc metamethod. */
1014
+ fin = lj_ctype_meta(cts, id, MM_gc);
1015
+ if (fin)
1016
+ crec_finalizer(J, trcd, 0, fin);
1017
+ }
1018
+
1019
+ /* Record argument conversions. */
1020
+ static TRef crec_call_args(jit_State *J, RecordFFData *rd,
1021
+ CTState *cts, CType *ct)
1022
+ {
1023
+ TRef args[CCI_NARGS_MAX];
1024
+ CTypeID fid;
1025
+ MSize i, n;
1026
+ TRef tr, *base;
1027
+ cTValue *o;
1028
+ #if LJ_TARGET_X86
1029
+ #if LJ_ABI_WIN
1030
+ TRef *arg0 = NULL, *arg1 = NULL;
1031
+ #endif
1032
+ int ngpr = 0;
1033
+ if (ctype_cconv(ct->info) == CTCC_THISCALL)
1034
+ ngpr = 1;
1035
+ else if (ctype_cconv(ct->info) == CTCC_FASTCALL)
1036
+ ngpr = 2;
1037
+ #endif
1038
+
1039
+ /* Skip initial attributes. */
1040
+ fid = ct->sib;
1041
+ while (fid) {
1042
+ CType *ctf = ctype_get(cts, fid);
1043
+ if (!ctype_isattrib(ctf->info)) break;
1044
+ fid = ctf->sib;
1045
+ }
1046
+ args[0] = TREF_NIL;
1047
+ for (n = 0, base = J->base+1, o = rd->argv+1; *base; n++, base++, o++) {
1048
+ CTypeID did;
1049
+ CType *d;
1050
+
1051
+ if (n >= CCI_NARGS_MAX)
1052
+ lj_trace_err(J, LJ_TRERR_NYICALL);
1053
+
1054
+ if (fid) { /* Get argument type from field. */
1055
+ CType *ctf = ctype_get(cts, fid);
1056
+ fid = ctf->sib;
1057
+ lua_assert(ctype_isfield(ctf->info));
1058
+ did = ctype_cid(ctf->info);
1059
+ } else {
1060
+ if (!(ct->info & CTF_VARARG))
1061
+ lj_trace_err(J, LJ_TRERR_NYICALL); /* Too many arguments. */
1062
+ did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */
1063
+ }
1064
+ d = ctype_raw(cts, did);
1065
+ if (!(ctype_isnum(d->info) || ctype_isptr(d->info) ||
1066
+ ctype_isenum(d->info)))
1067
+ lj_trace_err(J, LJ_TRERR_NYICALL);
1068
+ tr = crec_ct_tv(J, d, 0, *base, o);
1069
+ if (ctype_isinteger_or_bool(d->info)) {
1070
+ if (d->size < 4) {
1071
+ if ((d->info & CTF_UNSIGNED))
1072
+ tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_U8 : IRT_U16, 0);
1073
+ else
1074
+ tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_I8 : IRT_I16,IRCONV_SEXT);
1075
+ }
1076
+ } else if (LJ_SOFTFP && ctype_isfp(d->info) && d->size > 4) {
1077
+ lj_needsplit(J);
1078
+ }
1079
+ #if LJ_TARGET_X86
1080
+ /* 64 bit args must not end up in registers for fastcall/thiscall. */
1081
+ #if LJ_ABI_WIN
1082
+ if (!ctype_isfp(d->info)) {
1083
+ /* Sigh, the Windows/x86 ABI allows reordering across 64 bit args. */
1084
+ if (tref_typerange(tr, IRT_I64, IRT_U64)) {
1085
+ if (ngpr) {
1086
+ arg0 = &args[n]; args[n++] = TREF_NIL; ngpr--;
1087
+ if (ngpr) {
1088
+ arg1 = &args[n]; args[n++] = TREF_NIL; ngpr--;
1089
+ }
1090
+ }
1091
+ } else {
1092
+ if (arg0) { *arg0 = tr; arg0 = NULL; n--; continue; }
1093
+ if (arg1) { *arg1 = tr; arg1 = NULL; n--; continue; }
1094
+ if (ngpr) ngpr--;
1095
+ }
1096
+ }
1097
+ #else
1098
+ if (!ctype_isfp(d->info) && ngpr) {
1099
+ if (tref_typerange(tr, IRT_I64, IRT_U64)) {
1100
+ /* No reordering for other x86 ABIs. Simply add alignment args. */
1101
+ do { args[n++] = TREF_NIL; } while (--ngpr);
1102
+ } else {
1103
+ ngpr--;
1104
+ }
1105
+ }
1106
+ #endif
1107
+ #endif
1108
+ args[n] = tr;
1109
+ }
1110
+ tr = args[0];
1111
+ for (i = 1; i < n; i++)
1112
+ tr = emitir(IRT(IR_CARG, IRT_NIL), tr, args[i]);
1113
+ return tr;
1114
+ }
1115
+
1116
+ /* Create a snapshot for the caller, simulating a 'false' return value. */
1117
+ static void crec_snap_caller(jit_State *J)
1118
+ {
1119
+ lua_State *L = J->L;
1120
+ TValue *base = L->base, *top = L->top;
1121
+ const BCIns *pc = J->pc;
1122
+ TRef ftr = J->base[-1];
1123
+ ptrdiff_t delta;
1124
+ if (!frame_islua(base-1) || J->framedepth <= 0)
1125
+ lj_trace_err(J, LJ_TRERR_NYICALL);
1126
+ J->pc = frame_pc(base-1); delta = 1+LJ_FR2+bc_a(J->pc[-1]);
1127
+ L->top = base; L->base = base - delta;
1128
+ J->base[-1] = TREF_FALSE;
1129
+ J->base -= delta; J->baseslot -= (BCReg)delta;
1130
+ J->maxslot = (BCReg)delta; J->framedepth--;
1131
+ lj_snap_add(J);
1132
+ L->base = base; L->top = top;
1133
+ J->framedepth++; J->maxslot = 1;
1134
+ J->base += delta; J->baseslot += (BCReg)delta;
1135
+ J->base[-1] = ftr; J->pc = pc;
1136
+ }
1137
+
1138
+ /* Record function call. */
1139
+ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
1140
+ {
1141
+ CTState *cts = ctype_ctsG(J2G(J));
1142
+ CType *ct = ctype_raw(cts, cd->ctypeid);
1143
+ IRType tp = IRT_PTR;
1144
+ if (ctype_isptr(ct->info)) {
1145
+ tp = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
1146
+ ct = ctype_rawchild(cts, ct);
1147
+ }
1148
+ if (ctype_isfunc(ct->info)) {
1149
+ TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR);
1150
+ CType *ctr = ctype_rawchild(cts, ct);
1151
+ IRType t = crec_ct2irt(cts, ctr);
1152
+ TRef tr;
1153
+ TValue tv;
1154
+ /* Check for blacklisted C functions that might call a callback. */
1155
+ setlightudV(&tv,
1156
+ cdata_getptr(cdataptr(cd), (LJ_64 && tp == IRT_P64) ? 8 : 4));
1157
+ if (tvistrue(lj_tab_get(J->L, cts->miscmap, &tv)))
1158
+ lj_trace_err(J, LJ_TRERR_BLACKL);
1159
+ if (ctype_isvoid(ctr->info)) {
1160
+ t = IRT_NIL;
1161
+ rd->nres = 0;
1162
+ } else if (!(ctype_isnum(ctr->info) || ctype_isptr(ctr->info) ||
1163
+ ctype_isenum(ctr->info)) || t == IRT_CDATA) {
1164
+ lj_trace_err(J, LJ_TRERR_NYICALL);
1165
+ }
1166
+ if ((ct->info & CTF_VARARG)
1167
+ #if LJ_TARGET_X86
1168
+ || ctype_cconv(ct->info) != CTCC_CDECL
1169
+ #endif
1170
+ )
1171
+ func = emitir(IRT(IR_CARG, IRT_NIL), func,
1172
+ lj_ir_kint(J, ctype_typeid(cts, ct)));
1173
+ tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func);
1174
+ if (ctype_isbool(ctr->info)) {
1175
+ if (frame_islua(J->L->base-1) && bc_b(frame_pc(J->L->base-1)[-1]) == 1) {
1176
+ /* Don't check result if ignored. */
1177
+ tr = TREF_NIL;
1178
+ } else {
1179
+ crec_snap_caller(J);
1180
+ #if LJ_TARGET_X86ORX64
1181
+ /* Note: only the x86/x64 backend supports U8 and only for EQ(tr, 0). */
1182
+ lj_ir_set(J, IRTG(IR_NE, IRT_U8), tr, lj_ir_kint(J, 0));
1183
+ #else
1184
+ lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0));
1185
+ #endif
1186
+ J->postproc = LJ_POST_FIXGUARDSNAP;
1187
+ tr = TREF_TRUE;
1188
+ }
1189
+ } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) ||
1190
+ t == IRT_I64 || t == IRT_U64 || ctype_isenum(ctr->info)) {
1191
+ TRef trid = lj_ir_kint(J, ctype_cid(ct->info));
1192
+ tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr);
1193
+ if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
1194
+ } else if (t == IRT_FLOAT || t == IRT_U32) {
1195
+ tr = emitconv(tr, IRT_NUM, t, 0);
1196
+ } else if (t == IRT_I8 || t == IRT_I16) {
1197
+ tr = emitconv(tr, IRT_INT, t, IRCONV_SEXT);
1198
+ } else if (t == IRT_U8 || t == IRT_U16) {
1199
+ tr = emitconv(tr, IRT_INT, t, 0);
1200
+ }
1201
+ J->base[0] = tr;
1202
+ J->needsnap = 1;
1203
+ return 1;
1204
+ }
1205
+ return 0;
1206
+ }
1207
+
1208
+ void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd)
1209
+ {
1210
+ CTState *cts = ctype_ctsG(J2G(J));
1211
+ GCcdata *cd = argv2cdata(J, J->base[0], &rd->argv[0]);
1212
+ CTypeID id = cd->ctypeid;
1213
+ CType *ct;
1214
+ cTValue *tv;
1215
+ MMS mm = MM_call;
1216
+ if (id == CTID_CTYPEID) {
1217
+ id = crec_constructor(J, cd, J->base[0]);
1218
+ mm = MM_new;
1219
+ } else if (crec_call(J, rd, cd)) {
1220
+ return;
1221
+ }
1222
+ /* Record ctype __call/__new metamethod. */
1223
+ ct = ctype_raw(cts, id);
1224
+ tv = lj_ctype_meta(cts, ctype_isptr(ct->info) ? ctype_cid(ct->info) : id, mm);
1225
+ if (tv) {
1226
+ if (tvisfunc(tv)) {
1227
+ J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME;
1228
+ rd->nres = -1; /* Pending tailcall. */
1229
+ return;
1230
+ }
1231
+ } else if (mm == MM_new) {
1232
+ crec_alloc(J, rd, id);
1233
+ return;
1234
+ }
1235
+ /* No metamethod or NYI: non-function metamethods. */
1236
+ lj_trace_err(J, LJ_TRERR_BADTYPE);
1237
+ }
1238
+
1239
+ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
1240
+ {
1241
+ if (ctype_isnum(s[0]->info) && ctype_isnum(s[1]->info)) {
1242
+ IRType dt;
1243
+ CTypeID id;
1244
+ TRef tr;
1245
+ MSize i;
1246
+ IROp op;
1247
+ lj_needsplit(J);
1248
+ if (((s[0]->info & CTF_UNSIGNED) && s[0]->size == 8) ||
1249
+ ((s[1]->info & CTF_UNSIGNED) && s[1]->size == 8)) {
1250
+ dt = IRT_U64; id = CTID_UINT64;
1251
+ } else {
1252
+ dt = IRT_I64; id = CTID_INT64;
1253
+ if (mm < MM_add &&
1254
+ !((s[0]->info | s[1]->info) & CTF_FP) &&
1255
+ s[0]->size == 4 && s[1]->size == 4) { /* Try to narrow comparison. */
1256
+ if (!((s[0]->info ^ s[1]->info) & CTF_UNSIGNED) ||
1257
+ (tref_isk(sp[1]) && IR(tref_ref(sp[1]))->i >= 0)) {
1258
+ dt = (s[0]->info & CTF_UNSIGNED) ? IRT_U32 : IRT_INT;
1259
+ goto comp;
1260
+ } else if (tref_isk(sp[0]) && IR(tref_ref(sp[0]))->i >= 0) {
1261
+ dt = (s[1]->info & CTF_UNSIGNED) ? IRT_U32 : IRT_INT;
1262
+ goto comp;
1263
+ }
1264
+ }
1265
+ }
1266
+ for (i = 0; i < 2; i++) {
1267
+ IRType st = tref_type(sp[i]);
1268
+ if (st == IRT_NUM || st == IRT_FLOAT)
1269
+ sp[i] = emitconv(sp[i], dt, st, IRCONV_ANY);
1270
+ else if (!(st == IRT_I64 || st == IRT_U64))
1271
+ sp[i] = emitconv(sp[i], dt, IRT_INT,
1272
+ (s[i]->info & CTF_UNSIGNED) ? 0 : IRCONV_SEXT);
1273
+ }
1274
+ if (mm < MM_add) {
1275
+ comp:
1276
+ /* Assume true comparison. Fixup and emit pending guard later. */
1277
+ if (mm == MM_eq) {
1278
+ op = IR_EQ;
1279
+ } else {
1280
+ op = mm == MM_lt ? IR_LT : IR_LE;
1281
+ if (dt == IRT_U32 || dt == IRT_U64)
1282
+ op += (IR_ULT-IR_LT);
1283
+ }
1284
+ lj_ir_set(J, IRTG(op, dt), sp[0], sp[1]);
1285
+ J->postproc = LJ_POST_FIXGUARD;
1286
+ return TREF_TRUE;
1287
+ } else {
1288
+ tr = emitir(IRT(mm+(int)IR_ADD-(int)MM_add, dt), sp[0], sp[1]);
1289
+ }
1290
+ return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1291
+ }
1292
+ return 0;
1293
+ }
1294
+
1295
+ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm)
1296
+ {
1297
+ CTState *cts = ctype_ctsG(J2G(J));
1298
+ CType *ctp = s[0];
1299
+ if (ctype_isptr(ctp->info) || ctype_isrefarray(ctp->info)) {
1300
+ if ((mm == MM_sub || mm == MM_eq || mm == MM_lt || mm == MM_le) &&
1301
+ (ctype_isptr(s[1]->info) || ctype_isrefarray(s[1]->info))) {
1302
+ if (mm == MM_sub) { /* Pointer difference. */
1303
+ TRef tr;
1304
+ CTSize sz = lj_ctype_size(cts, ctype_cid(ctp->info));
1305
+ if (sz == 0 || (sz & (sz-1)) != 0)
1306
+ return 0; /* NYI: integer division. */
1307
+ tr = emitir(IRT(IR_SUB, IRT_INTP), sp[0], sp[1]);
1308
+ tr = emitir(IRT(IR_BSAR, IRT_INTP), tr, lj_ir_kint(J, lj_fls(sz)));
1309
+ #if LJ_64
1310
+ tr = emitconv(tr, IRT_NUM, IRT_INTP, 0);
1311
+ #endif
1312
+ return tr;
1313
+ } else { /* Pointer comparison (unsigned). */
1314
+ /* Assume true comparison. Fixup and emit pending guard later. */
1315
+ IROp op = mm == MM_eq ? IR_EQ : mm == MM_lt ? IR_ULT : IR_ULE;
1316
+ lj_ir_set(J, IRTG(op, IRT_PTR), sp[0], sp[1]);
1317
+ J->postproc = LJ_POST_FIXGUARD;
1318
+ return TREF_TRUE;
1319
+ }
1320
+ }
1321
+ if (!((mm == MM_add || mm == MM_sub) && ctype_isnum(s[1]->info)))
1322
+ return 0;
1323
+ } else if (mm == MM_add && ctype_isnum(ctp->info) &&
1324
+ (ctype_isptr(s[1]->info) || ctype_isrefarray(s[1]->info))) {
1325
+ TRef tr = sp[0]; sp[0] = sp[1]; sp[1] = tr; /* Swap pointer and index. */
1326
+ ctp = s[1];
1327
+ } else {
1328
+ return 0;
1329
+ }
1330
+ {
1331
+ TRef tr = sp[1];
1332
+ IRType t = tref_type(tr);
1333
+ CTSize sz = lj_ctype_size(cts, ctype_cid(ctp->info));
1334
+ CTypeID id;
1335
+ #if LJ_64
1336
+ if (t == IRT_NUM || t == IRT_FLOAT)
1337
+ tr = emitconv(tr, IRT_INTP, t, IRCONV_ANY);
1338
+ else if (!(t == IRT_I64 || t == IRT_U64))
1339
+ tr = emitconv(tr, IRT_INTP, IRT_INT,
1340
+ ((t - IRT_I8) & 1) ? 0 : IRCONV_SEXT);
1341
+ #else
1342
+ if (!tref_typerange(sp[1], IRT_I8, IRT_U32)) {
1343
+ tr = emitconv(tr, IRT_INTP, t,
1344
+ (t == IRT_NUM || t == IRT_FLOAT) ? IRCONV_ANY : 0);
1345
+ }
1346
+ #endif
1347
+ tr = emitir(IRT(IR_MUL, IRT_INTP), tr, lj_ir_kintp(J, sz));
1348
+ tr = emitir(IRT(mm+(int)IR_ADD-(int)MM_add, IRT_PTR), sp[0], tr);
1349
+ id = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(ctp->info)),
1350
+ CTSIZE_PTR);
1351
+ return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1352
+ }
1353
+ }
1354
+
1355
+ /* Record ctype arithmetic metamethods. */
1356
+ static TRef crec_arith_meta(jit_State *J, TRef *sp, CType **s, CTState *cts,
1357
+ RecordFFData *rd)
1358
+ {
1359
+ cTValue *tv = NULL;
1360
+ if (J->base[0]) {
1361
+ if (tviscdata(&rd->argv[0])) {
1362
+ CTypeID id = argv2cdata(J, J->base[0], &rd->argv[0])->ctypeid;
1363
+ CType *ct = ctype_raw(cts, id);
1364
+ if (ctype_isptr(ct->info)) id = ctype_cid(ct->info);
1365
+ tv = lj_ctype_meta(cts, id, (MMS)rd->data);
1366
+ }
1367
+ if (!tv && J->base[1] && tviscdata(&rd->argv[1])) {
1368
+ CTypeID id = argv2cdata(J, J->base[1], &rd->argv[1])->ctypeid;
1369
+ CType *ct = ctype_raw(cts, id);
1370
+ if (ctype_isptr(ct->info)) id = ctype_cid(ct->info);
1371
+ tv = lj_ctype_meta(cts, id, (MMS)rd->data);
1372
+ }
1373
+ }
1374
+ if (tv) {
1375
+ if (tvisfunc(tv)) {
1376
+ J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME;
1377
+ rd->nres = -1; /* Pending tailcall. */
1378
+ return 0;
1379
+ } /* NYI: non-function metamethods. */
1380
+ } else if ((MMS)rd->data == MM_eq) { /* Fallback cdata pointer comparison. */
1381
+ if (sp[0] && sp[1] && ctype_isnum(s[0]->info) == ctype_isnum(s[1]->info)) {
1382
+ /* Assume true comparison. Fixup and emit pending guard later. */
1383
+ lj_ir_set(J, IRTG(IR_EQ, IRT_PTR), sp[0], sp[1]);
1384
+ J->postproc = LJ_POST_FIXGUARD;
1385
+ return TREF_TRUE;
1386
+ } else {
1387
+ return TREF_FALSE;
1388
+ }
1389
+ }
1390
+ lj_trace_err(J, LJ_TRERR_BADTYPE);
1391
+ return 0;
1392
+ }
1393
+
1394
+ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
1395
+ {
1396
+ CTState *cts = ctype_ctsG(J2G(J));
1397
+ TRef sp[2];
1398
+ CType *s[2];
1399
+ MSize i;
1400
+ for (i = 0; i < 2; i++) {
1401
+ TRef tr = J->base[i];
1402
+ CType *ct = ctype_get(cts, CTID_DOUBLE);
1403
+ if (!tr) {
1404
+ lj_trace_err(J, LJ_TRERR_BADTYPE);
1405
+ } else if (tref_iscdata(tr)) {
1406
+ CTypeID id = argv2cdata(J, tr, &rd->argv[i])->ctypeid;
1407
+ IRType t;
1408
+ ct = ctype_raw(cts, id);
1409
+ t = crec_ct2irt(cts, ct);
1410
+ if (ctype_isptr(ct->info)) { /* Resolve pointer or reference. */
1411
+ tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_PTR);
1412
+ if (ctype_isref(ct->info)) {
1413
+ ct = ctype_rawchild(cts, ct);
1414
+ t = crec_ct2irt(cts, ct);
1415
+ }
1416
+ } else if (t == IRT_I64 || t == IRT_U64) {
1417
+ tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_INT64);
1418
+ lj_needsplit(J);
1419
+ goto ok;
1420
+ } else if (t == IRT_INT || t == IRT_U32) {
1421
+ tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_INT);
1422
+ if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1423
+ goto ok;
1424
+ } else if (ctype_isfunc(ct->info)) {
1425
+ tr = emitir(IRT(IR_FLOAD, IRT_PTR), tr, IRFL_CDATA_PTR);
1426
+ ct = ctype_get(cts,
1427
+ lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR));
1428
+ goto ok;
1429
+ } else {
1430
+ tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata)));
1431
+ }
1432
+ if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1433
+ if (ctype_isnum(ct->info)) {
1434
+ if (t == IRT_CDATA) {
1435
+ tr = 0;
1436
+ } else {
1437
+ if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
1438
+ tr = emitir(IRT(IR_XLOAD, t), tr, 0);
1439
+ }
1440
+ }
1441
+ } else if (tref_isnil(tr)) {
1442
+ tr = lj_ir_kptr(J, NULL);
1443
+ ct = ctype_get(cts, CTID_P_VOID);
1444
+ } else if (tref_isinteger(tr)) {
1445
+ ct = ctype_get(cts, CTID_INT32);
1446
+ } else if (tref_isstr(tr)) {
1447
+ TRef tr2 = J->base[1-i];
1448
+ CTypeID id = argv2cdata(J, tr2, &rd->argv[1-i])->ctypeid;
1449
+ ct = ctype_raw(cts, id);
1450
+ if (ctype_isenum(ct->info)) { /* Match string against enum constant. */
1451
+ GCstr *str = strV(&rd->argv[i]);
1452
+ CTSize ofs;
1453
+ CType *cct = lj_ctype_getfield(cts, ct, str, &ofs);
1454
+ if (cct && ctype_isconstval(cct->info)) {
1455
+ /* Specialize to the name of the enum constant. */
1456
+ emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, str));
1457
+ ct = ctype_child(cts, cct);
1458
+ tr = lj_ir_kint(J, (int32_t)ofs);
1459
+ } else { /* Interpreter will throw or return false. */
1460
+ ct = ctype_get(cts, CTID_P_VOID);
1461
+ }
1462
+ } else if (ctype_isptr(ct->info)) {
1463
+ tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCstr)));
1464
+ } else {
1465
+ ct = ctype_get(cts, CTID_P_VOID);
1466
+ }
1467
+ } else if (!tref_isnum(tr)) {
1468
+ tr = 0;
1469
+ ct = ctype_get(cts, CTID_P_VOID);
1470
+ }
1471
+ ok:
1472
+ s[i] = ct;
1473
+ sp[i] = tr;
1474
+ }
1475
+ {
1476
+ TRef tr;
1477
+ if (!(tr = crec_arith_int64(J, sp, s, (MMS)rd->data)) &&
1478
+ !(tr = crec_arith_ptr(J, sp, s, (MMS)rd->data)) &&
1479
+ !(tr = crec_arith_meta(J, sp, s, cts, rd)))
1480
+ return;
1481
+ J->base[0] = tr;
1482
+ /* Fixup cdata comparisons, too. Avoids some cdata escapes. */
1483
+ if (J->postproc == LJ_POST_FIXGUARD && frame_iscont(J->L->base-1) &&
1484
+ !irt_isguard(J->guardemit)) {
1485
+ const BCIns *pc = frame_contpc(J->L->base-1) - 1;
1486
+ if (bc_op(*pc) <= BC_ISNEP) {
1487
+ J2G(J)->tmptv.u64 = (uint64_t)(uintptr_t)pc;
1488
+ J->postproc = LJ_POST_FIXCOMP;
1489
+ }
1490
+ }
1491
+ }
1492
+ }
1493
+
1494
+ /* -- C library namespace metamethods ------------------------------------- */
1495
+
1496
+ void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd)
1497
+ {
1498
+ CTState *cts = ctype_ctsG(J2G(J));
1499
+ if (tref_isudata(J->base[0]) && tref_isstr(J->base[1]) &&
1500
+ udataV(&rd->argv[0])->udtype == UDTYPE_FFI_CLIB) {
1501
+ CLibrary *cl = (CLibrary *)uddata(udataV(&rd->argv[0]));
1502
+ GCstr *name = strV(&rd->argv[1]);
1503
+ CType *ct;
1504
+ CTypeID id = lj_ctype_getname(cts, &ct, name, CLNS_INDEX);
1505
+ cTValue *tv = lj_tab_getstr(cl->cache, name);
1506
+ rd->nres = rd->data;
1507
+ if (id && tv && !tvisnil(tv)) {
1508
+ /* Specialize to the symbol name and make the result a constant. */
1509
+ emitir(IRTG(IR_EQ, IRT_STR), J->base[1], lj_ir_kstr(J, name));
1510
+ if (ctype_isconstval(ct->info)) {
1511
+ if (ct->size >= 0x80000000u &&
1512
+ (ctype_child(cts, ct)->info & CTF_UNSIGNED))
1513
+ J->base[0] = lj_ir_knum(J, (lua_Number)(uint32_t)ct->size);
1514
+ else
1515
+ J->base[0] = lj_ir_kint(J, (int32_t)ct->size);
1516
+ } else if (ctype_isextern(ct->info)) {
1517
+ CTypeID sid = ctype_cid(ct->info);
1518
+ void *sp = *(void **)cdataptr(cdataV(tv));
1519
+ TRef ptr;
1520
+ ct = ctype_raw(cts, sid);
1521
+ if (LJ_64 && !checkptr32(sp))
1522
+ ptr = lj_ir_kintp(J, (uintptr_t)sp);
1523
+ else
1524
+ ptr = lj_ir_kptr(J, sp);
1525
+ if (rd->data) {
1526
+ J->base[0] = crec_tv_ct(J, ct, sid, ptr);
1527
+ } else {
1528
+ J->needsnap = 1;
1529
+ crec_ct_tv(J, ct, ptr, J->base[2], &rd->argv[2]);
1530
+ }
1531
+ } else {
1532
+ J->base[0] = lj_ir_kgc(J, obj2gco(cdataV(tv)), IRT_CDATA);
1533
+ }
1534
+ } else {
1535
+ lj_trace_err(J, LJ_TRERR_NOCACHE);
1536
+ }
1537
+ } /* else: interpreter will throw. */
1538
+ }
1539
+
1540
+ /* -- FFI library functions ----------------------------------------------- */
1541
+
1542
+ static TRef crec_toint(jit_State *J, CTState *cts, TRef sp, TValue *sval)
1543
+ {
1544
+ return crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0, sp, sval);
1545
+ }
1546
+
1547
+ void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd)
1548
+ {
1549
+ crec_alloc(J, rd, argv2ctype(J, J->base[0], &rd->argv[0]));
1550
+ }
1551
+
1552
+ void LJ_FASTCALL recff_ffi_errno(jit_State *J, RecordFFData *rd)
1553
+ {
1554
+ UNUSED(rd);
1555
+ if (J->base[0])
1556
+ lj_trace_err(J, LJ_TRERR_NYICALL);
1557
+ J->base[0] = lj_ir_call(J, IRCALL_lj_vm_errno);
1558
+ }
1559
+
1560
+ void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd)
1561
+ {
1562
+ CTState *cts = ctype_ctsG(J2G(J));
1563
+ TRef tr = J->base[0];
1564
+ if (tr) {
1565
+ TRef trlen = J->base[1];
1566
+ if (!tref_isnil(trlen)) {
1567
+ trlen = crec_toint(J, cts, trlen, &rd->argv[1]);
1568
+ tr = crec_ct_tv(J, ctype_get(cts, CTID_P_CVOID), 0, tr, &rd->argv[0]);
1569
+ } else {
1570
+ tr = crec_ct_tv(J, ctype_get(cts, CTID_P_CCHAR), 0, tr, &rd->argv[0]);
1571
+ trlen = lj_ir_call(J, IRCALL_strlen, tr);
1572
+ }
1573
+ J->base[0] = emitir(IRT(IR_XSNEW, IRT_STR), tr, trlen);
1574
+ } /* else: interpreter will throw. */
1575
+ }
1576
+
1577
+ void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd)
1578
+ {
1579
+ CTState *cts = ctype_ctsG(J2G(J));
1580
+ TRef trdst = J->base[0], trsrc = J->base[1], trlen = J->base[2];
1581
+ if (trdst && trsrc && (trlen || tref_isstr(trsrc))) {
1582
+ trdst = crec_ct_tv(J, ctype_get(cts, CTID_P_VOID), 0, trdst, &rd->argv[0]);
1583
+ trsrc = crec_ct_tv(J, ctype_get(cts, CTID_P_CVOID), 0, trsrc, &rd->argv[1]);
1584
+ if (trlen) {
1585
+ trlen = crec_toint(J, cts, trlen, &rd->argv[2]);
1586
+ } else {
1587
+ trlen = emitir(IRTI(IR_FLOAD), J->base[1], IRFL_STR_LEN);
1588
+ trlen = emitir(IRTI(IR_ADD), trlen, lj_ir_kint(J, 1));
1589
+ }
1590
+ rd->nres = 0;
1591
+ crec_copy(J, trdst, trsrc, trlen, NULL);
1592
+ } /* else: interpreter will throw. */
1593
+ }
1594
+
1595
+ void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd)
1596
+ {
1597
+ CTState *cts = ctype_ctsG(J2G(J));
1598
+ TRef trdst = J->base[0], trlen = J->base[1], trfill = J->base[2];
1599
+ if (trdst && trlen) {
1600
+ CTSize step = 1;
1601
+ if (tviscdata(&rd->argv[0])) { /* Get alignment of original destination. */
1602
+ CTSize sz;
1603
+ CType *ct = ctype_raw(cts, cdataV(&rd->argv[0])->ctypeid);
1604
+ if (ctype_isptr(ct->info))
1605
+ ct = ctype_rawchild(cts, ct);
1606
+ step = (1u<<ctype_align(lj_ctype_info(cts, ctype_typeid(cts, ct), &sz)));
1607
+ }
1608
+ trdst = crec_ct_tv(J, ctype_get(cts, CTID_P_VOID), 0, trdst, &rd->argv[0]);
1609
+ trlen = crec_toint(J, cts, trlen, &rd->argv[1]);
1610
+ if (trfill)
1611
+ trfill = crec_toint(J, cts, trfill, &rd->argv[2]);
1612
+ else
1613
+ trfill = lj_ir_kint(J, 0);
1614
+ rd->nres = 0;
1615
+ crec_fill(J, trdst, trlen, trfill, step);
1616
+ } /* else: interpreter will throw. */
1617
+ }
1618
+
1619
+ void LJ_FASTCALL recff_ffi_typeof(jit_State *J, RecordFFData *rd)
1620
+ {
1621
+ if (tref_iscdata(J->base[0])) {
1622
+ TRef trid = lj_ir_kint(J, argv2ctype(J, J->base[0], &rd->argv[0]));
1623
+ J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA),
1624
+ lj_ir_kint(J, CTID_CTYPEID), trid);
1625
+ } else {
1626
+ setfuncV(J->L, &J->errinfo, J->fn);
1627
+ lj_trace_err_info(J, LJ_TRERR_NYIFFU);
1628
+ }
1629
+ }
1630
+
1631
+ void LJ_FASTCALL recff_ffi_istype(jit_State *J, RecordFFData *rd)
1632
+ {
1633
+ argv2ctype(J, J->base[0], &rd->argv[0]);
1634
+ if (tref_iscdata(J->base[1])) {
1635
+ argv2ctype(J, J->base[1], &rd->argv[1]);
1636
+ J->postproc = LJ_POST_FIXBOOL;
1637
+ J->base[0] = TREF_TRUE;
1638
+ } else {
1639
+ J->base[0] = TREF_FALSE;
1640
+ }
1641
+ }
1642
+
1643
+ void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd)
1644
+ {
1645
+ if (tref_isstr(J->base[0])) {
1646
+ /* Specialize to the ABI string to make the boolean result a constant. */
1647
+ emitir(IRTG(IR_EQ, IRT_STR), J->base[0], lj_ir_kstr(J, strV(&rd->argv[0])));
1648
+ J->postproc = LJ_POST_FIXBOOL;
1649
+ J->base[0] = TREF_TRUE;
1650
+ } else {
1651
+ lj_trace_err(J, LJ_TRERR_BADTYPE);
1652
+ }
1653
+ }
1654
+
1655
+ /* Record ffi.sizeof(), ffi.alignof(), ffi.offsetof(). */
1656
+ void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd)
1657
+ {
1658
+ CTypeID id = argv2ctype(J, J->base[0], &rd->argv[0]);
1659
+ if (rd->data == FF_ffi_sizeof) {
1660
+ CType *ct = lj_ctype_rawref(ctype_ctsG(J2G(J)), id);
1661
+ if (ctype_isvltype(ct->info))
1662
+ lj_trace_err(J, LJ_TRERR_BADTYPE);
1663
+ } else if (rd->data == FF_ffi_offsetof) { /* Specialize to the field name. */
1664
+ if (!tref_isstr(J->base[1]))
1665
+ lj_trace_err(J, LJ_TRERR_BADTYPE);
1666
+ emitir(IRTG(IR_EQ, IRT_STR), J->base[1], lj_ir_kstr(J, strV(&rd->argv[1])));
1667
+ rd->nres = 3; /* Just in case. */
1668
+ }
1669
+ J->postproc = LJ_POST_FIXCONST;
1670
+ J->base[0] = J->base[1] = J->base[2] = TREF_NIL;
1671
+ }
1672
+
1673
+ void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd)
1674
+ {
1675
+ argv2cdata(J, J->base[0], &rd->argv[0]);
1676
+ if (!J->base[1])
1677
+ lj_trace_err(J, LJ_TRERR_BADTYPE);
1678
+ crec_finalizer(J, J->base[0], J->base[1], &rd->argv[1]);
1679
+ }
1680
+
1681
+ /* -- 64 bit bit.* library functions -------------------------------------- */
1682
+
1683
+ /* Determine bit operation type from argument type. */
1684
+ static CTypeID crec_bit64_type(CTState *cts, cTValue *tv)
1685
+ {
1686
+ if (tviscdata(tv)) {
1687
+ CType *ct = lj_ctype_rawref(cts, cdataV(tv)->ctypeid);
1688
+ if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1689
+ if ((ct->info & (CTMASK_NUM|CTF_BOOL|CTF_FP|CTF_UNSIGNED)) ==
1690
+ CTINFO(CT_NUM, CTF_UNSIGNED) && ct->size == 8)
1691
+ return CTID_UINT64; /* Use uint64_t, since it has the highest rank. */
1692
+ return CTID_INT64; /* Otherwise use int64_t. */
1693
+ }
1694
+ return 0; /* Use regular 32 bit ops. */
1695
+ }
1696
+
1697
+ void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd)
1698
+ {
1699
+ CTState *cts = ctype_ctsG(J2G(J));
1700
+ TRef tr = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0,
1701
+ J->base[0], &rd->argv[0]);
1702
+ if (!tref_isinteger(tr))
1703
+ tr = emitconv(tr, IRT_INT, tref_type(tr), 0);
1704
+ J->base[0] = tr;
1705
+ }
1706
+
1707
+ int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd)
1708
+ {
1709
+ CTState *cts = ctype_ctsG(J2G(J));
1710
+ CTypeID id = crec_bit64_type(cts, &rd->argv[0]);
1711
+ if (id) {
1712
+ TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
1713
+ tr = emitir(IRT(rd->data, id-CTID_INT64+IRT_I64), tr, 0);
1714
+ J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1715
+ return 1;
1716
+ }
1717
+ return 0;
1718
+ }
1719
+
1720
+ int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd)
1721
+ {
1722
+ CTState *cts = ctype_ctsG(J2G(J));
1723
+ CTypeID id = 0;
1724
+ MSize i;
1725
+ for (i = 0; J->base[i] != 0; i++) {
1726
+ CTypeID aid = crec_bit64_type(cts, &rd->argv[i]);
1727
+ if (id < aid) id = aid; /* Determine highest type rank of all arguments. */
1728
+ }
1729
+ if (id) {
1730
+ CType *ct = ctype_get(cts, id);
1731
+ uint32_t ot = IRT(rd->data, id-CTID_INT64+IRT_I64);
1732
+ TRef tr = crec_ct_tv(J, ct, 0, J->base[0], &rd->argv[0]);
1733
+ for (i = 1; J->base[i] != 0; i++) {
1734
+ TRef tr2 = crec_ct_tv(J, ct, 0, J->base[i], &rd->argv[i]);
1735
+ tr = emitir(ot, tr, tr2);
1736
+ }
1737
+ J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1738
+ return 1;
1739
+ }
1740
+ return 0;
1741
+ }
1742
+
1743
+ int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd)
1744
+ {
1745
+ CTState *cts = ctype_ctsG(J2G(J));
1746
+ CTypeID id;
1747
+ TRef tsh = 0;
1748
+ if (J->base[0] && tref_iscdata(J->base[1])) {
1749
+ tsh = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0,
1750
+ J->base[1], &rd->argv[1]);
1751
+ if (!tref_isinteger(tsh))
1752
+ tsh = emitconv(tsh, IRT_INT, tref_type(tsh), 0);
1753
+ J->base[1] = tsh;
1754
+ }
1755
+ id = crec_bit64_type(cts, &rd->argv[0]);
1756
+ if (id) {
1757
+ TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
1758
+ uint32_t op = rd->data;
1759
+ if (!tsh) tsh = lj_opt_narrow_tobit(J, J->base[1]);
1760
+ if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
1761
+ !tref_isk(tsh))
1762
+ tsh = emitir(IRTI(IR_BAND), tsh, lj_ir_kint(J, 63));
1763
+ #ifdef LJ_TARGET_UNIFYROT
1764
+ if (op == (LJ_TARGET_UNIFYROT == 1 ? IR_BROR : IR_BROL)) {
1765
+ op = LJ_TARGET_UNIFYROT == 1 ? IR_BROL : IR_BROR;
1766
+ tsh = emitir(IRTI(IR_NEG), tsh, tsh);
1767
+ }
1768
+ #endif
1769
+ tr = emitir(IRT(op, id-CTID_INT64+IRT_I64), tr, tsh);
1770
+ J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1771
+ return 1;
1772
+ }
1773
+ return 0;
1774
+ }
1775
+
1776
+ TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr)
1777
+ {
1778
+ CTState *cts = ctype_ctsG(J2G(J));
1779
+ CTypeID id = crec_bit64_type(cts, &rd->argv[0]);
1780
+ TRef tr, trsf = J->base[1];
1781
+ SFormat sf = (STRFMT_UINT|STRFMT_T_HEX);
1782
+ int32_t n;
1783
+ if (trsf) {
1784
+ CTypeID id2 = 0;
1785
+ n = (int32_t)lj_carith_check64(J->L, 2, &id2);
1786
+ if (id2)
1787
+ trsf = crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0, trsf, &rd->argv[1]);
1788
+ else
1789
+ trsf = lj_opt_narrow_tobit(J, trsf);
1790
+ emitir(IRTGI(IR_EQ), trsf, lj_ir_kint(J, n)); /* Specialize to n. */
1791
+ } else {
1792
+ n = id ? 16 : 8;
1793
+ }
1794
+ if (n < 0) { n = -n; sf |= STRFMT_F_UPPER; }
1795
+ sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
1796
+ if (id) {
1797
+ tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
1798
+ if (n < 16)
1799
+ tr = emitir(IRT(IR_BAND, IRT_U64), tr,
1800
+ lj_ir_kint64(J, ((uint64_t)1 << 4*n)-1));
1801
+ } else {
1802
+ tr = lj_opt_narrow_tobit(J, J->base[0]);
1803
+ if (n < 8)
1804
+ tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (int32_t)((1u << 4*n)-1)));
1805
+ tr = emitconv(tr, IRT_U64, IRT_INT, 0); /* No sign-extension. */
1806
+ lj_needsplit(J);
1807
+ }
1808
+ return lj_ir_call(J, IRCALL_lj_strfmt_putfxint, hdr, lj_ir_kint(J, sf), tr);
1809
+ }
1810
+
1811
+ /* -- Miscellaneous library functions ------------------------------------- */
1812
+
1813
+ void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd)
1814
+ {
1815
+ CTState *cts = ctype_ctsG(J2G(J));
1816
+ CType *d, *ct = lj_ctype_rawref(cts, cdataV(&rd->argv[0])->ctypeid);
1817
+ if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1818
+ if (ctype_isnum(ct->info) || ctype_iscomplex(ct->info)) {
1819
+ if (ctype_isinteger_or_bool(ct->info) && ct->size <= 4 &&
1820
+ !(ct->size == 4 && (ct->info & CTF_UNSIGNED)))
1821
+ d = ctype_get(cts, CTID_INT32);
1822
+ else
1823
+ d = ctype_get(cts, CTID_DOUBLE);
1824
+ J->base[0] = crec_ct_tv(J, d, 0, J->base[0], &rd->argv[0]);
1825
+ } else {
1826
+ J->base[0] = TREF_NIL;
1827
+ }
1828
+ }
1829
+
1830
+ #undef IR
1831
+ #undef emitir
1832
+ #undef emitconv
1833
+
1834
+ #endif