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,29 @@
1
+ /*
2
+ ** FFI C library loader.
3
+ ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
4
+ */
5
+
6
+ #ifndef _LJ_CLIB_H
7
+ #define _LJ_CLIB_H
8
+
9
+ #include "lj_obj.h"
10
+
11
+ #if LJ_HASFFI
12
+
13
+ /* Namespace for C library indexing. */
14
+ #define CLNS_INDEX ((1u<<CT_FUNC)|(1u<<CT_EXTERN)|(1u<<CT_CONSTVAL))
15
+
16
+ /* C library namespace. */
17
+ typedef struct CLibrary {
18
+ void *handle; /* Opaque handle for dynamic library loader. */
19
+ GCtab *cache; /* Cache for resolved symbols. Anchored in ud->env. */
20
+ } CLibrary;
21
+
22
+ LJ_FUNC TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name);
23
+ LJ_FUNC void lj_clib_load(lua_State *L, GCtab *mt, GCstr *name, int global);
24
+ LJ_FUNC void lj_clib_unload(CLibrary *cl);
25
+ LJ_FUNC void lj_clib_default(lua_State *L, GCtab *mt);
26
+
27
+ #endif
28
+
29
+ #endif
@@ -0,0 +1,1862 @@
1
+ /*
2
+ ** C declaration parser.
3
+ ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
4
+ */
5
+
6
+ #include "lj_obj.h"
7
+
8
+ #if LJ_HASFFI
9
+
10
+ #include "lj_gc.h"
11
+ #include "lj_err.h"
12
+ #include "lj_buf.h"
13
+ #include "lj_ctype.h"
14
+ #include "lj_cparse.h"
15
+ #include "lj_frame.h"
16
+ #include "lj_vm.h"
17
+ #include "lj_char.h"
18
+ #include "lj_strscan.h"
19
+ #include "lj_strfmt.h"
20
+
21
+ /*
22
+ ** Important note: this is NOT a validating C parser! This is a minimal
23
+ ** C declaration parser, solely for use by the LuaJIT FFI.
24
+ **
25
+ ** It ought to return correct results for properly formed C declarations,
26
+ ** but it may accept some invalid declarations, too (and return nonsense).
27
+ ** Also, it shows rather generic error messages to avoid unnecessary bloat.
28
+ ** If in doubt, please check the input against your favorite C compiler.
29
+ */
30
+
31
+ /* -- C lexer ------------------------------------------------------------- */
32
+
33
+ /* C lexer token names. */
34
+ static const char *const ctoknames[] = {
35
+ #define CTOKSTR(name, str) str,
36
+ CTOKDEF(CTOKSTR)
37
+ #undef CTOKSTR
38
+ NULL
39
+ };
40
+
41
+ /* Forward declaration. */
42
+ LJ_NORET static void cp_err(CPState *cp, ErrMsg em);
43
+
44
+ static const char *cp_tok2str(CPState *cp, CPToken tok)
45
+ {
46
+ lua_assert(tok < CTOK_FIRSTDECL);
47
+ if (tok > CTOK_OFS)
48
+ return ctoknames[tok-CTOK_OFS-1];
49
+ else if (!lj_char_iscntrl(tok))
50
+ return lj_strfmt_pushf(cp->L, "%c", tok);
51
+ else
52
+ return lj_strfmt_pushf(cp->L, "char(%d)", tok);
53
+ }
54
+
55
+ /* End-of-line? */
56
+ static LJ_AINLINE int cp_iseol(CPChar c)
57
+ {
58
+ return (c == '\n' || c == '\r');
59
+ }
60
+
61
+ /* Peek next raw character. */
62
+ static LJ_AINLINE CPChar cp_rawpeek(CPState *cp)
63
+ {
64
+ return (CPChar)(uint8_t)(*cp->p);
65
+ }
66
+
67
+ static LJ_NOINLINE CPChar cp_get_bs(CPState *cp);
68
+
69
+ /* Get next character. */
70
+ static LJ_AINLINE CPChar cp_get(CPState *cp)
71
+ {
72
+ cp->c = (CPChar)(uint8_t)(*cp->p++);
73
+ if (LJ_LIKELY(cp->c != '\\')) return cp->c;
74
+ return cp_get_bs(cp);
75
+ }
76
+
77
+ /* Transparently skip backslash-escaped line breaks. */
78
+ static LJ_NOINLINE CPChar cp_get_bs(CPState *cp)
79
+ {
80
+ CPChar c2, c = cp_rawpeek(cp);
81
+ if (!cp_iseol(c)) return cp->c;
82
+ cp->p++;
83
+ c2 = cp_rawpeek(cp);
84
+ if (cp_iseol(c2) && c2 != c) cp->p++;
85
+ cp->linenumber++;
86
+ return cp_get(cp);
87
+ }
88
+
89
+ /* Save character in buffer. */
90
+ static LJ_AINLINE void cp_save(CPState *cp, CPChar c)
91
+ {
92
+ lj_buf_putb(&cp->sb, c);
93
+ }
94
+
95
+ /* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */
96
+ static void cp_newline(CPState *cp)
97
+ {
98
+ CPChar c = cp_rawpeek(cp);
99
+ if (cp_iseol(c) && c != cp->c) cp->p++;
100
+ cp->linenumber++;
101
+ }
102
+
103
+ LJ_NORET static void cp_errmsg(CPState *cp, CPToken tok, ErrMsg em, ...)
104
+ {
105
+ const char *msg, *tokstr;
106
+ lua_State *L;
107
+ va_list argp;
108
+ if (tok == 0) {
109
+ tokstr = NULL;
110
+ } else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING ||
111
+ tok >= CTOK_FIRSTDECL) {
112
+ if (sbufP(&cp->sb) == sbufB(&cp->sb)) cp_save(cp, '$');
113
+ cp_save(cp, '\0');
114
+ tokstr = sbufB(&cp->sb);
115
+ } else {
116
+ tokstr = cp_tok2str(cp, tok);
117
+ }
118
+ L = cp->L;
119
+ va_start(argp, em);
120
+ msg = lj_strfmt_pushvf(L, err2msg(em), argp);
121
+ va_end(argp);
122
+ if (tokstr)
123
+ msg = lj_strfmt_pushf(L, err2msg(LJ_ERR_XNEAR), msg, tokstr);
124
+ if (cp->linenumber > 1)
125
+ msg = lj_strfmt_pushf(L, "%s at line %d", msg, cp->linenumber);
126
+ lj_err_callermsg(L, msg);
127
+ }
128
+
129
+ LJ_NORET LJ_NOINLINE static void cp_err_token(CPState *cp, CPToken tok)
130
+ {
131
+ cp_errmsg(cp, cp->tok, LJ_ERR_XTOKEN, cp_tok2str(cp, tok));
132
+ }
133
+
134
+ LJ_NORET LJ_NOINLINE static void cp_err_badidx(CPState *cp, CType *ct)
135
+ {
136
+ GCstr *s = lj_ctype_repr(cp->cts->L, ctype_typeid(cp->cts, ct), NULL);
137
+ cp_errmsg(cp, 0, LJ_ERR_FFI_BADIDX, strdata(s));
138
+ }
139
+
140
+ LJ_NORET LJ_NOINLINE static void cp_err(CPState *cp, ErrMsg em)
141
+ {
142
+ cp_errmsg(cp, 0, em);
143
+ }
144
+
145
+ /* -- Main lexical scanner ------------------------------------------------ */
146
+
147
+ /* Parse number literal. Only handles int32_t/uint32_t right now. */
148
+ static CPToken cp_number(CPState *cp)
149
+ {
150
+ StrScanFmt fmt;
151
+ TValue o;
152
+ do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
153
+ cp_save(cp, '\0');
154
+ fmt = lj_strscan_scan((const uint8_t *)sbufB(&cp->sb), &o, STRSCAN_OPT_C);
155
+ if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32;
156
+ else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32;
157
+ else if (!(cp->mode & CPARSE_MODE_SKIP))
158
+ cp_errmsg(cp, CTOK_INTEGER, LJ_ERR_XNUMBER);
159
+ cp->val.u32 = (uint32_t)o.i;
160
+ return CTOK_INTEGER;
161
+ }
162
+
163
+ /* Parse identifier or keyword. */
164
+ static CPToken cp_ident(CPState *cp)
165
+ {
166
+ do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
167
+ cp->str = lj_buf_str(cp->L, &cp->sb);
168
+ cp->val.id = lj_ctype_getname(cp->cts, &cp->ct, cp->str, cp->tmask);
169
+ if (ctype_type(cp->ct->info) == CT_KW)
170
+ return ctype_cid(cp->ct->info);
171
+ return CTOK_IDENT;
172
+ }
173
+
174
+ /* Parse parameter. */
175
+ static CPToken cp_param(CPState *cp)
176
+ {
177
+ CPChar c = cp_get(cp);
178
+ TValue *o = cp->param;
179
+ if (lj_char_isident(c) || c == '$') /* Reserve $xyz for future extensions. */
180
+ cp_errmsg(cp, c, LJ_ERR_XSYNTAX);
181
+ if (!o || o >= cp->L->top)
182
+ cp_err(cp, LJ_ERR_FFI_NUMPARAM);
183
+ cp->param = o+1;
184
+ if (tvisstr(o)) {
185
+ cp->str = strV(o);
186
+ cp->val.id = 0;
187
+ cp->ct = &cp->cts->tab[0];
188
+ return CTOK_IDENT;
189
+ } else if (tvisnumber(o)) {
190
+ cp->val.i32 = numberVint(o);
191
+ cp->val.id = CTID_INT32;
192
+ return CTOK_INTEGER;
193
+ } else {
194
+ GCcdata *cd;
195
+ if (!tviscdata(o))
196
+ lj_err_argtype(cp->L, (int)(o-cp->L->base)+1, "type parameter");
197
+ cd = cdataV(o);
198
+ if (cd->ctypeid == CTID_CTYPEID)
199
+ cp->val.id = *(CTypeID *)cdataptr(cd);
200
+ else
201
+ cp->val.id = cd->ctypeid;
202
+ return '$';
203
+ }
204
+ }
205
+
206
+ /* Parse string or character constant. */
207
+ static CPToken cp_string(CPState *cp)
208
+ {
209
+ CPChar delim = cp->c;
210
+ cp_get(cp);
211
+ while (cp->c != delim) {
212
+ CPChar c = cp->c;
213
+ if (c == '\0') cp_errmsg(cp, CTOK_EOF, LJ_ERR_XSTR);
214
+ if (c == '\\') {
215
+ c = cp_get(cp);
216
+ switch (c) {
217
+ case '\0': cp_errmsg(cp, CTOK_EOF, LJ_ERR_XSTR); break;
218
+ case 'a': c = '\a'; break;
219
+ case 'b': c = '\b'; break;
220
+ case 'f': c = '\f'; break;
221
+ case 'n': c = '\n'; break;
222
+ case 'r': c = '\r'; break;
223
+ case 't': c = '\t'; break;
224
+ case 'v': c = '\v'; break;
225
+ case 'e': c = 27; break;
226
+ case 'x':
227
+ c = 0;
228
+ while (lj_char_isxdigit(cp_get(cp)))
229
+ c = (c<<4) + (lj_char_isdigit(cp->c) ? cp->c-'0' : (cp->c&15)+9);
230
+ cp_save(cp, (c & 0xff));
231
+ continue;
232
+ default:
233
+ if (lj_char_isdigit(c)) {
234
+ c -= '0';
235
+ if (lj_char_isdigit(cp_get(cp))) {
236
+ c = c*8 + (cp->c - '0');
237
+ if (lj_char_isdigit(cp_get(cp))) {
238
+ c = c*8 + (cp->c - '0');
239
+ cp_get(cp);
240
+ }
241
+ }
242
+ cp_save(cp, (c & 0xff));
243
+ continue;
244
+ }
245
+ break;
246
+ }
247
+ }
248
+ cp_save(cp, c);
249
+ cp_get(cp);
250
+ }
251
+ cp_get(cp);
252
+ if (delim == '"') {
253
+ cp->str = lj_buf_str(cp->L, &cp->sb);
254
+ return CTOK_STRING;
255
+ } else {
256
+ if (sbuflen(&cp->sb) != 1) cp_err_token(cp, '\'');
257
+ cp->val.i32 = (int32_t)(char)*sbufB(&cp->sb);
258
+ cp->val.id = CTID_INT32;
259
+ return CTOK_INTEGER;
260
+ }
261
+ }
262
+
263
+ /* Skip C comment. */
264
+ static void cp_comment_c(CPState *cp)
265
+ {
266
+ do {
267
+ if (cp_get(cp) == '*') {
268
+ do {
269
+ if (cp_get(cp) == '/') { cp_get(cp); return; }
270
+ } while (cp->c == '*');
271
+ }
272
+ if (cp_iseol(cp->c)) cp_newline(cp);
273
+ } while (cp->c != '\0');
274
+ }
275
+
276
+ /* Skip C++ comment. */
277
+ static void cp_comment_cpp(CPState *cp)
278
+ {
279
+ while (!cp_iseol(cp_get(cp)) && cp->c != '\0')
280
+ ;
281
+ }
282
+
283
+ /* Lexical scanner for C. Only a minimal subset is implemented. */
284
+ static CPToken cp_next_(CPState *cp)
285
+ {
286
+ lj_buf_reset(&cp->sb);
287
+ for (;;) {
288
+ if (lj_char_isident(cp->c))
289
+ return lj_char_isdigit(cp->c) ? cp_number(cp) : cp_ident(cp);
290
+ switch (cp->c) {
291
+ case '\n': case '\r': cp_newline(cp); /* fallthrough. */
292
+ case ' ': case '\t': case '\v': case '\f': cp_get(cp); break;
293
+ case '"': case '\'': return cp_string(cp);
294
+ case '/':
295
+ if (cp_get(cp) == '*') cp_comment_c(cp);
296
+ else if (cp->c == '/') cp_comment_cpp(cp);
297
+ else return '/';
298
+ break;
299
+ case '|':
300
+ if (cp_get(cp) != '|') return '|'; cp_get(cp); return CTOK_OROR;
301
+ case '&':
302
+ if (cp_get(cp) != '&') return '&'; cp_get(cp); return CTOK_ANDAND;
303
+ case '=':
304
+ if (cp_get(cp) != '=') return '='; cp_get(cp); return CTOK_EQ;
305
+ case '!':
306
+ if (cp_get(cp) != '=') return '!'; cp_get(cp); return CTOK_NE;
307
+ case '<':
308
+ if (cp_get(cp) == '=') { cp_get(cp); return CTOK_LE; }
309
+ else if (cp->c == '<') { cp_get(cp); return CTOK_SHL; }
310
+ return '<';
311
+ case '>':
312
+ if (cp_get(cp) == '=') { cp_get(cp); return CTOK_GE; }
313
+ else if (cp->c == '>') { cp_get(cp); return CTOK_SHR; }
314
+ return '>';
315
+ case '-':
316
+ if (cp_get(cp) != '>') return '-'; cp_get(cp); return CTOK_DEREF;
317
+ case '$':
318
+ return cp_param(cp);
319
+ case '\0': return CTOK_EOF;
320
+ default: { CPToken c = cp->c; cp_get(cp); return c; }
321
+ }
322
+ }
323
+ }
324
+
325
+ static LJ_NOINLINE CPToken cp_next(CPState *cp)
326
+ {
327
+ return (cp->tok = cp_next_(cp));
328
+ }
329
+
330
+ /* -- C parser ------------------------------------------------------------ */
331
+
332
+ /* Namespaces for resolving identifiers. */
333
+ #define CPNS_DEFAULT \
334
+ ((1u<<CT_KW)|(1u<<CT_TYPEDEF)|(1u<<CT_FUNC)|(1u<<CT_EXTERN)|(1u<<CT_CONSTVAL))
335
+ #define CPNS_STRUCT ((1u<<CT_KW)|(1u<<CT_STRUCT)|(1u<<CT_ENUM))
336
+
337
+ typedef CTypeID CPDeclIdx; /* Index into declaration stack. */
338
+ typedef uint32_t CPscl; /* Storage class flags. */
339
+
340
+ /* Type declaration context. */
341
+ typedef struct CPDecl {
342
+ CPDeclIdx top; /* Top of declaration stack. */
343
+ CPDeclIdx pos; /* Insertion position in declaration chain. */
344
+ CPDeclIdx specpos; /* Saved position for declaration specifier. */
345
+ uint32_t mode; /* Declarator mode. */
346
+ CPState *cp; /* C parser state. */
347
+ GCstr *name; /* Name of declared identifier (if direct). */
348
+ GCstr *redir; /* Redirected symbol name. */
349
+ CTypeID nameid; /* Existing typedef for declared identifier. */
350
+ CTInfo attr; /* Attributes. */
351
+ CTInfo fattr; /* Function attributes. */
352
+ CTInfo specattr; /* Saved attributes. */
353
+ CTInfo specfattr; /* Saved function attributes. */
354
+ CTSize bits; /* Field size in bits (if any). */
355
+ CType stack[CPARSE_MAX_DECLSTACK]; /* Type declaration stack. */
356
+ } CPDecl;
357
+
358
+ /* Forward declarations. */
359
+ static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl);
360
+ static void cp_declarator(CPState *cp, CPDecl *decl);
361
+ static CTypeID cp_decl_abstract(CPState *cp);
362
+
363
+ /* Initialize C parser state. Caller must set up: L, p, srcname, mode. */
364
+ static void cp_init(CPState *cp)
365
+ {
366
+ cp->linenumber = 1;
367
+ cp->depth = 0;
368
+ cp->curpack = 0;
369
+ cp->packstack[0] = 255;
370
+ lj_buf_init(cp->L, &cp->sb);
371
+ lua_assert(cp->p != NULL);
372
+ cp_get(cp); /* Read-ahead first char. */
373
+ cp->tok = 0;
374
+ cp->tmask = CPNS_DEFAULT;
375
+ cp_next(cp); /* Read-ahead first token. */
376
+ }
377
+
378
+ /* Cleanup C parser state. */
379
+ static void cp_cleanup(CPState *cp)
380
+ {
381
+ global_State *g = G(cp->L);
382
+ lj_buf_free(g, &cp->sb);
383
+ }
384
+
385
+ /* Check and consume optional token. */
386
+ static int cp_opt(CPState *cp, CPToken tok)
387
+ {
388
+ if (cp->tok == tok) { cp_next(cp); return 1; }
389
+ return 0;
390
+ }
391
+
392
+ /* Check and consume token. */
393
+ static void cp_check(CPState *cp, CPToken tok)
394
+ {
395
+ if (cp->tok != tok) cp_err_token(cp, tok);
396
+ cp_next(cp);
397
+ }
398
+
399
+ /* Check if the next token may start a type declaration. */
400
+ static int cp_istypedecl(CPState *cp)
401
+ {
402
+ if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECL) return 1;
403
+ if (cp->tok == CTOK_IDENT && ctype_istypedef(cp->ct->info)) return 1;
404
+ if (cp->tok == '$') return 1;
405
+ return 0;
406
+ }
407
+
408
+ /* -- Constant expression evaluator --------------------------------------- */
409
+
410
+ /* Forward declarations. */
411
+ static void cp_expr_unary(CPState *cp, CPValue *k);
412
+ static void cp_expr_sub(CPState *cp, CPValue *k, int pri);
413
+
414
+ /* Please note that type handling is very weak here. Most ops simply
415
+ ** assume integer operands. Accessors are only needed to compute types and
416
+ ** return synthetic values. The only purpose of the expression evaluator
417
+ ** is to compute the values of constant expressions one would typically
418
+ ** find in C header files. And again: this is NOT a validating C parser!
419
+ */
420
+
421
+ /* Parse comma separated expression and return last result. */
422
+ static void cp_expr_comma(CPState *cp, CPValue *k)
423
+ {
424
+ do { cp_expr_sub(cp, k, 0); } while (cp_opt(cp, ','));
425
+ }
426
+
427
+ /* Parse sizeof/alignof operator. */
428
+ static void cp_expr_sizeof(CPState *cp, CPValue *k, int wantsz)
429
+ {
430
+ CTSize sz;
431
+ CTInfo info;
432
+ if (cp_opt(cp, '(')) {
433
+ if (cp_istypedecl(cp))
434
+ k->id = cp_decl_abstract(cp);
435
+ else
436
+ cp_expr_comma(cp, k);
437
+ cp_check(cp, ')');
438
+ } else {
439
+ cp_expr_unary(cp, k);
440
+ }
441
+ info = lj_ctype_info(cp->cts, k->id, &sz);
442
+ if (wantsz) {
443
+ if (sz != CTSIZE_INVALID)
444
+ k->u32 = sz;
445
+ else if (k->id != CTID_A_CCHAR) /* Special case for sizeof("string"). */
446
+ cp_err(cp, LJ_ERR_FFI_INVSIZE);
447
+ } else {
448
+ k->u32 = 1u << ctype_align(info);
449
+ }
450
+ k->id = CTID_UINT32; /* Really size_t. */
451
+ }
452
+
453
+ /* Parse prefix operators. */
454
+ static void cp_expr_prefix(CPState *cp, CPValue *k)
455
+ {
456
+ if (cp->tok == CTOK_INTEGER) {
457
+ *k = cp->val; cp_next(cp);
458
+ } else if (cp_opt(cp, '+')) {
459
+ cp_expr_unary(cp, k); /* Nothing to do (well, integer promotion). */
460
+ } else if (cp_opt(cp, '-')) {
461
+ cp_expr_unary(cp, k); k->i32 = -k->i32;
462
+ } else if (cp_opt(cp, '~')) {
463
+ cp_expr_unary(cp, k); k->i32 = ~k->i32;
464
+ } else if (cp_opt(cp, '!')) {
465
+ cp_expr_unary(cp, k); k->i32 = !k->i32; k->id = CTID_INT32;
466
+ } else if (cp_opt(cp, '(')) {
467
+ if (cp_istypedecl(cp)) { /* Cast operator. */
468
+ CTypeID id = cp_decl_abstract(cp);
469
+ cp_check(cp, ')');
470
+ cp_expr_unary(cp, k);
471
+ k->id = id; /* No conversion performed. */
472
+ } else { /* Sub-expression. */
473
+ cp_expr_comma(cp, k);
474
+ cp_check(cp, ')');
475
+ }
476
+ } else if (cp_opt(cp, '*')) { /* Indirection. */
477
+ CType *ct;
478
+ cp_expr_unary(cp, k);
479
+ ct = lj_ctype_rawref(cp->cts, k->id);
480
+ if (!ctype_ispointer(ct->info))
481
+ cp_err_badidx(cp, ct);
482
+ k->u32 = 0; k->id = ctype_cid(ct->info);
483
+ } else if (cp_opt(cp, '&')) { /* Address operator. */
484
+ cp_expr_unary(cp, k);
485
+ k->id = lj_ctype_intern(cp->cts, CTINFO(CT_PTR, CTALIGN_PTR+k->id),
486
+ CTSIZE_PTR);
487
+ } else if (cp_opt(cp, CTOK_SIZEOF)) {
488
+ cp_expr_sizeof(cp, k, 1);
489
+ } else if (cp_opt(cp, CTOK_ALIGNOF)) {
490
+ cp_expr_sizeof(cp, k, 0);
491
+ } else if (cp->tok == CTOK_IDENT) {
492
+ if (ctype_type(cp->ct->info) == CT_CONSTVAL) {
493
+ k->u32 = cp->ct->size; k->id = ctype_cid(cp->ct->info);
494
+ } else if (ctype_type(cp->ct->info) == CT_EXTERN) {
495
+ k->u32 = cp->val.id; k->id = ctype_cid(cp->ct->info);
496
+ } else if (ctype_type(cp->ct->info) == CT_FUNC) {
497
+ k->u32 = cp->val.id; k->id = cp->val.id;
498
+ } else {
499
+ goto err_expr;
500
+ }
501
+ cp_next(cp);
502
+ } else if (cp->tok == CTOK_STRING) {
503
+ CTSize sz = cp->str->len;
504
+ while (cp_next(cp) == CTOK_STRING)
505
+ sz += cp->str->len;
506
+ k->u32 = sz + 1;
507
+ k->id = CTID_A_CCHAR;
508
+ } else {
509
+ err_expr:
510
+ cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
511
+ }
512
+ }
513
+
514
+ /* Parse postfix operators. */
515
+ static void cp_expr_postfix(CPState *cp, CPValue *k)
516
+ {
517
+ for (;;) {
518
+ CType *ct;
519
+ if (cp_opt(cp, '[')) { /* Array/pointer index. */
520
+ CPValue k2;
521
+ cp_expr_comma(cp, &k2);
522
+ ct = lj_ctype_rawref(cp->cts, k->id);
523
+ if (!ctype_ispointer(ct->info)) {
524
+ ct = lj_ctype_rawref(cp->cts, k2.id);
525
+ if (!ctype_ispointer(ct->info))
526
+ cp_err_badidx(cp, ct);
527
+ }
528
+ cp_check(cp, ']');
529
+ k->u32 = 0;
530
+ } else if (cp->tok == '.' || cp->tok == CTOK_DEREF) { /* Struct deref. */
531
+ CTSize ofs;
532
+ CType *fct;
533
+ ct = lj_ctype_rawref(cp->cts, k->id);
534
+ if (cp->tok == CTOK_DEREF) {
535
+ if (!ctype_ispointer(ct->info))
536
+ cp_err_badidx(cp, ct);
537
+ ct = lj_ctype_rawref(cp->cts, ctype_cid(ct->info));
538
+ }
539
+ cp_next(cp);
540
+ if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT);
541
+ if (!ctype_isstruct(ct->info) || ct->size == CTSIZE_INVALID ||
542
+ !(fct = lj_ctype_getfield(cp->cts, ct, cp->str, &ofs)) ||
543
+ ctype_isbitfield(fct->info)) {
544
+ GCstr *s = lj_ctype_repr(cp->cts->L, ctype_typeid(cp->cts, ct), NULL);
545
+ cp_errmsg(cp, 0, LJ_ERR_FFI_BADMEMBER, strdata(s), strdata(cp->str));
546
+ }
547
+ ct = fct;
548
+ k->u32 = ctype_isconstval(ct->info) ? ct->size : 0;
549
+ cp_next(cp);
550
+ } else {
551
+ return;
552
+ }
553
+ k->id = ctype_cid(ct->info);
554
+ }
555
+ }
556
+
557
+ /* Parse infix operators. */
558
+ static void cp_expr_infix(CPState *cp, CPValue *k, int pri)
559
+ {
560
+ CPValue k2;
561
+ k2.u32 = 0; k2.id = 0; /* Silence the compiler. */
562
+ for (;;) {
563
+ switch (pri) {
564
+ case 0:
565
+ if (cp_opt(cp, '?')) {
566
+ CPValue k3;
567
+ cp_expr_comma(cp, &k2); /* Right-associative. */
568
+ cp_check(cp, ':');
569
+ cp_expr_sub(cp, &k3, 0);
570
+ k->u32 = k->u32 ? k2.u32 : k3.u32;
571
+ k->id = k2.id > k3.id ? k2.id : k3.id;
572
+ continue;
573
+ }
574
+ case 1:
575
+ if (cp_opt(cp, CTOK_OROR)) {
576
+ cp_expr_sub(cp, &k2, 2); k->i32 = k->u32 || k2.u32; k->id = CTID_INT32;
577
+ continue;
578
+ }
579
+ case 2:
580
+ if (cp_opt(cp, CTOK_ANDAND)) {
581
+ cp_expr_sub(cp, &k2, 3); k->i32 = k->u32 && k2.u32; k->id = CTID_INT32;
582
+ continue;
583
+ }
584
+ case 3:
585
+ if (cp_opt(cp, '|')) {
586
+ cp_expr_sub(cp, &k2, 4); k->u32 = k->u32 | k2.u32; goto arith_result;
587
+ }
588
+ case 4:
589
+ if (cp_opt(cp, '^')) {
590
+ cp_expr_sub(cp, &k2, 5); k->u32 = k->u32 ^ k2.u32; goto arith_result;
591
+ }
592
+ case 5:
593
+ if (cp_opt(cp, '&')) {
594
+ cp_expr_sub(cp, &k2, 6); k->u32 = k->u32 & k2.u32; goto arith_result;
595
+ }
596
+ case 6:
597
+ if (cp_opt(cp, CTOK_EQ)) {
598
+ cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 == k2.u32; k->id = CTID_INT32;
599
+ continue;
600
+ } else if (cp_opt(cp, CTOK_NE)) {
601
+ cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 != k2.u32; k->id = CTID_INT32;
602
+ continue;
603
+ }
604
+ case 7:
605
+ if (cp_opt(cp, '<')) {
606
+ cp_expr_sub(cp, &k2, 8);
607
+ if (k->id == CTID_INT32 && k2.id == CTID_INT32)
608
+ k->i32 = k->i32 < k2.i32;
609
+ else
610
+ k->i32 = k->u32 < k2.u32;
611
+ k->id = CTID_INT32;
612
+ continue;
613
+ } else if (cp_opt(cp, '>')) {
614
+ cp_expr_sub(cp, &k2, 8);
615
+ if (k->id == CTID_INT32 && k2.id == CTID_INT32)
616
+ k->i32 = k->i32 > k2.i32;
617
+ else
618
+ k->i32 = k->u32 > k2.u32;
619
+ k->id = CTID_INT32;
620
+ continue;
621
+ } else if (cp_opt(cp, CTOK_LE)) {
622
+ cp_expr_sub(cp, &k2, 8);
623
+ if (k->id == CTID_INT32 && k2.id == CTID_INT32)
624
+ k->i32 = k->i32 <= k2.i32;
625
+ else
626
+ k->i32 = k->u32 <= k2.u32;
627
+ k->id = CTID_INT32;
628
+ continue;
629
+ } else if (cp_opt(cp, CTOK_GE)) {
630
+ cp_expr_sub(cp, &k2, 8);
631
+ if (k->id == CTID_INT32 && k2.id == CTID_INT32)
632
+ k->i32 = k->i32 >= k2.i32;
633
+ else
634
+ k->i32 = k->u32 >= k2.u32;
635
+ k->id = CTID_INT32;
636
+ continue;
637
+ }
638
+ case 8:
639
+ if (cp_opt(cp, CTOK_SHL)) {
640
+ cp_expr_sub(cp, &k2, 9); k->u32 = k->u32 << k2.u32;
641
+ continue;
642
+ } else if (cp_opt(cp, CTOK_SHR)) {
643
+ cp_expr_sub(cp, &k2, 9);
644
+ if (k->id == CTID_INT32)
645
+ k->i32 = k->i32 >> k2.i32;
646
+ else
647
+ k->u32 = k->u32 >> k2.u32;
648
+ continue;
649
+ }
650
+ case 9:
651
+ if (cp_opt(cp, '+')) {
652
+ cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 + k2.u32;
653
+ arith_result:
654
+ if (k2.id > k->id) k->id = k2.id; /* Trivial promotion to unsigned. */
655
+ continue;
656
+ } else if (cp_opt(cp, '-')) {
657
+ cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 - k2.u32; goto arith_result;
658
+ }
659
+ case 10:
660
+ if (cp_opt(cp, '*')) {
661
+ cp_expr_unary(cp, &k2); k->u32 = k->u32 * k2.u32; goto arith_result;
662
+ } else if (cp_opt(cp, '/')) {
663
+ cp_expr_unary(cp, &k2);
664
+ if (k2.id > k->id) k->id = k2.id; /* Trivial promotion to unsigned. */
665
+ if (k2.u32 == 0 ||
666
+ (k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1))
667
+ cp_err(cp, LJ_ERR_BADVAL);
668
+ if (k->id == CTID_INT32)
669
+ k->i32 = k->i32 / k2.i32;
670
+ else
671
+ k->u32 = k->u32 / k2.u32;
672
+ continue;
673
+ } else if (cp_opt(cp, '%')) {
674
+ cp_expr_unary(cp, &k2);
675
+ if (k2.id > k->id) k->id = k2.id; /* Trivial promotion to unsigned. */
676
+ if (k2.u32 == 0 ||
677
+ (k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1))
678
+ cp_err(cp, LJ_ERR_BADVAL);
679
+ if (k->id == CTID_INT32)
680
+ k->i32 = k->i32 % k2.i32;
681
+ else
682
+ k->u32 = k->u32 % k2.u32;
683
+ continue;
684
+ }
685
+ default:
686
+ return;
687
+ }
688
+ }
689
+ }
690
+
691
+ /* Parse and evaluate unary expression. */
692
+ static void cp_expr_unary(CPState *cp, CPValue *k)
693
+ {
694
+ if (++cp->depth > CPARSE_MAX_DECLDEPTH) cp_err(cp, LJ_ERR_XLEVELS);
695
+ cp_expr_prefix(cp, k);
696
+ cp_expr_postfix(cp, k);
697
+ cp->depth--;
698
+ }
699
+
700
+ /* Parse and evaluate sub-expression. */
701
+ static void cp_expr_sub(CPState *cp, CPValue *k, int pri)
702
+ {
703
+ cp_expr_unary(cp, k);
704
+ cp_expr_infix(cp, k, pri);
705
+ }
706
+
707
+ /* Parse constant integer expression. */
708
+ static void cp_expr_kint(CPState *cp, CPValue *k)
709
+ {
710
+ CType *ct;
711
+ cp_expr_sub(cp, k, 0);
712
+ ct = ctype_raw(cp->cts, k->id);
713
+ if (!ctype_isinteger(ct->info)) cp_err(cp, LJ_ERR_BADVAL);
714
+ }
715
+
716
+ /* Parse (non-negative) size expression. */
717
+ static CTSize cp_expr_ksize(CPState *cp)
718
+ {
719
+ CPValue k;
720
+ cp_expr_kint(cp, &k);
721
+ if (k.u32 >= 0x80000000u) cp_err(cp, LJ_ERR_FFI_INVSIZE);
722
+ return k.u32;
723
+ }
724
+
725
+ /* -- Type declaration stack management ----------------------------------- */
726
+
727
+ /* Add declaration element behind the insertion position. */
728
+ static CPDeclIdx cp_add(CPDecl *decl, CTInfo info, CTSize size)
729
+ {
730
+ CPDeclIdx top = decl->top;
731
+ if (top >= CPARSE_MAX_DECLSTACK) cp_err(decl->cp, LJ_ERR_XLEVELS);
732
+ decl->stack[top].info = info;
733
+ decl->stack[top].size = size;
734
+ decl->stack[top].sib = 0;
735
+ setgcrefnull(decl->stack[top].name);
736
+ decl->stack[top].next = decl->stack[decl->pos].next;
737
+ decl->stack[decl->pos].next = (CTypeID1)top;
738
+ decl->top = top+1;
739
+ return top;
740
+ }
741
+
742
+ /* Push declaration element before the insertion position. */
743
+ static CPDeclIdx cp_push(CPDecl *decl, CTInfo info, CTSize size)
744
+ {
745
+ return (decl->pos = cp_add(decl, info, size));
746
+ }
747
+
748
+ /* Push or merge attributes. */
749
+ static void cp_push_attributes(CPDecl *decl)
750
+ {
751
+ CType *ct = &decl->stack[decl->pos];
752
+ if (ctype_isfunc(ct->info)) { /* Ok to modify in-place. */
753
+ #if LJ_TARGET_X86
754
+ if ((decl->fattr & CTFP_CCONV))
755
+ ct->info = (ct->info & (CTMASK_NUM|CTF_VARARG|CTMASK_CID)) +
756
+ (decl->fattr & ~CTMASK_CID);
757
+ #endif
758
+ } else {
759
+ if ((decl->attr & CTFP_ALIGNED) && !(decl->mode & CPARSE_MODE_FIELD))
760
+ cp_push(decl, CTINFO(CT_ATTRIB, CTATTRIB(CTA_ALIGN)),
761
+ ctype_align(decl->attr));
762
+ }
763
+ }
764
+
765
+ /* Push unrolled type to declaration stack and merge qualifiers. */
766
+ static void cp_push_type(CPDecl *decl, CTypeID id)
767
+ {
768
+ CType *ct = ctype_get(decl->cp->cts, id);
769
+ CTInfo info = ct->info;
770
+ CTSize size = ct->size;
771
+ switch (ctype_type(info)) {
772
+ case CT_STRUCT: case CT_ENUM:
773
+ cp_push(decl, CTINFO(CT_TYPEDEF, id), 0); /* Don't copy unique types. */
774
+ if ((decl->attr & CTF_QUAL)) { /* Push unmerged qualifiers. */
775
+ cp_push(decl, CTINFO(CT_ATTRIB, CTATTRIB(CTA_QUAL)),
776
+ (decl->attr & CTF_QUAL));
777
+ decl->attr &= ~CTF_QUAL;
778
+ }
779
+ break;
780
+ case CT_ATTRIB:
781
+ if (ctype_isxattrib(info, CTA_QUAL))
782
+ decl->attr &= ~size; /* Remove redundant qualifiers. */
783
+ cp_push_type(decl, ctype_cid(info)); /* Unroll. */
784
+ cp_push(decl, info & ~CTMASK_CID, size); /* Copy type. */
785
+ break;
786
+ case CT_ARRAY:
787
+ if ((ct->info & (CTF_VECTOR|CTF_COMPLEX))) {
788
+ info |= (decl->attr & CTF_QUAL);
789
+ decl->attr &= ~CTF_QUAL;
790
+ }
791
+ cp_push_type(decl, ctype_cid(info)); /* Unroll. */
792
+ cp_push(decl, info & ~CTMASK_CID, size); /* Copy type. */
793
+ decl->stack[decl->pos].sib = 1; /* Mark as already checked and sized. */
794
+ /* Note: this is not copied to the ct->sib in the C type table. */
795
+ break;
796
+ case CT_FUNC:
797
+ /* Copy type, link parameters (shared). */
798
+ decl->stack[cp_push(decl, info, size)].sib = ct->sib;
799
+ break;
800
+ default:
801
+ /* Copy type, merge common qualifiers. */
802
+ cp_push(decl, info|(decl->attr & CTF_QUAL), size);
803
+ decl->attr &= ~CTF_QUAL;
804
+ break;
805
+ }
806
+ }
807
+
808
+ /* Consume the declaration element chain and intern the C type. */
809
+ static CTypeID cp_decl_intern(CPState *cp, CPDecl *decl)
810
+ {
811
+ CTypeID id = 0;
812
+ CPDeclIdx idx = 0;
813
+ CTSize csize = CTSIZE_INVALID;
814
+ CTSize cinfo = 0;
815
+ do {
816
+ CType *ct = &decl->stack[idx];
817
+ CTInfo info = ct->info;
818
+ CTInfo size = ct->size;
819
+ /* The cid is already part of info for copies of pointers/functions. */
820
+ idx = ct->next;
821
+ if (ctype_istypedef(info)) {
822
+ lua_assert(id == 0);
823
+ id = ctype_cid(info);
824
+ /* Always refetch info/size, since struct/enum may have been completed. */
825
+ cinfo = ctype_get(cp->cts, id)->info;
826
+ csize = ctype_get(cp->cts, id)->size;
827
+ lua_assert(ctype_isstruct(cinfo) || ctype_isenum(cinfo));
828
+ } else if (ctype_isfunc(info)) { /* Intern function. */
829
+ CType *fct;
830
+ CTypeID fid;
831
+ CTypeID sib;
832
+ if (id) {
833
+ CType *refct = ctype_raw(cp->cts, id);
834
+ /* Reject function or refarray return types. */
835
+ if (ctype_isfunc(refct->info) || ctype_isrefarray(refct->info))
836
+ cp_err(cp, LJ_ERR_FFI_INVTYPE);
837
+ }
838
+ /* No intervening attributes allowed, skip forward. */
839
+ while (idx) {
840
+ CType *ctn = &decl->stack[idx];
841
+ if (!ctype_isattrib(ctn->info)) break;
842
+ idx = ctn->next; /* Skip attribute. */
843
+ }
844
+ sib = ct->sib; /* Next line may reallocate the C type table. */
845
+ fid = lj_ctype_new(cp->cts, &fct);
846
+ csize = CTSIZE_INVALID;
847
+ fct->info = cinfo = info + id;
848
+ fct->size = size;
849
+ fct->sib = sib;
850
+ id = fid;
851
+ } else if (ctype_isattrib(info)) {
852
+ if (ctype_isxattrib(info, CTA_QUAL))
853
+ cinfo |= size;
854
+ else if (ctype_isxattrib(info, CTA_ALIGN))
855
+ CTF_INSERT(cinfo, ALIGN, size);
856
+ id = lj_ctype_intern(cp->cts, info+id, size);
857
+ /* Inherit csize/cinfo from original type. */
858
+ } else {
859
+ if (ctype_isnum(info)) { /* Handle mode/vector-size attributes. */
860
+ lua_assert(id == 0);
861
+ if (!(info & CTF_BOOL)) {
862
+ CTSize msize = ctype_msizeP(decl->attr);
863
+ CTSize vsize = ctype_vsizeP(decl->attr);
864
+ if (msize && (!(info & CTF_FP) || (msize == 4 || msize == 8))) {
865
+ CTSize malign = lj_fls(msize);
866
+ if (malign > 4) malign = 4; /* Limit alignment. */
867
+ CTF_INSERT(info, ALIGN, malign);
868
+ size = msize; /* Override size via mode. */
869
+ }
870
+ if (vsize) { /* Vector size set? */
871
+ CTSize esize = lj_fls(size);
872
+ if (vsize >= esize) {
873
+ /* Intern the element type first. */
874
+ id = lj_ctype_intern(cp->cts, info, size);
875
+ /* Then create a vector (array) with vsize alignment. */
876
+ size = (1u << vsize);
877
+ if (vsize > 4) vsize = 4; /* Limit alignment. */
878
+ if (ctype_align(info) > vsize) vsize = ctype_align(info);
879
+ info = CTINFO(CT_ARRAY, (info & CTF_QUAL) + CTF_VECTOR +
880
+ CTALIGN(vsize));
881
+ }
882
+ }
883
+ }
884
+ } else if (ctype_isptr(info)) {
885
+ /* Reject pointer/ref to ref. */
886
+ if (id && ctype_isref(ctype_raw(cp->cts, id)->info))
887
+ cp_err(cp, LJ_ERR_FFI_INVTYPE);
888
+ if (ctype_isref(info)) {
889
+ info &= ~CTF_VOLATILE; /* Refs are always const, never volatile. */
890
+ /* No intervening attributes allowed, skip forward. */
891
+ while (idx) {
892
+ CType *ctn = &decl->stack[idx];
893
+ if (!ctype_isattrib(ctn->info)) break;
894
+ idx = ctn->next; /* Skip attribute. */
895
+ }
896
+ }
897
+ } else if (ctype_isarray(info)) { /* Check for valid array size etc. */
898
+ if (ct->sib == 0) { /* Only check/size arrays not copied by unroll. */
899
+ if (ctype_isref(cinfo)) /* Reject arrays of refs. */
900
+ cp_err(cp, LJ_ERR_FFI_INVTYPE);
901
+ /* Reject VLS or unknown-sized types. */
902
+ if (ctype_isvltype(cinfo) || csize == CTSIZE_INVALID)
903
+ cp_err(cp, LJ_ERR_FFI_INVSIZE);
904
+ /* a[] and a[?] keep their invalid size. */
905
+ if (size != CTSIZE_INVALID) {
906
+ uint64_t xsz = (uint64_t)size * csize;
907
+ if (xsz >= 0x80000000u) cp_err(cp, LJ_ERR_FFI_INVSIZE);
908
+ size = (CTSize)xsz;
909
+ }
910
+ }
911
+ if ((cinfo & CTF_ALIGN) > (info & CTF_ALIGN)) /* Find max. align. */
912
+ info = (info & ~CTF_ALIGN) | (cinfo & CTF_ALIGN);
913
+ info |= (cinfo & CTF_QUAL); /* Inherit qual. */
914
+ } else {
915
+ lua_assert(ctype_isvoid(info));
916
+ }
917
+ csize = size;
918
+ cinfo = info+id;
919
+ id = lj_ctype_intern(cp->cts, info+id, size);
920
+ }
921
+ } while (idx);
922
+ return id;
923
+ }
924
+
925
+ /* -- C declaration parser ------------------------------------------------ */
926
+
927
+ #define H_(le, be) LJ_ENDIAN_SELECT(0x##le, 0x##be)
928
+
929
+ /* Reset declaration state to declaration specifier. */
930
+ static void cp_decl_reset(CPDecl *decl)
931
+ {
932
+ decl->pos = decl->specpos;
933
+ decl->top = decl->specpos+1;
934
+ decl->stack[decl->specpos].next = 0;
935
+ decl->attr = decl->specattr;
936
+ decl->fattr = decl->specfattr;
937
+ decl->name = NULL;
938
+ decl->redir = NULL;
939
+ }
940
+
941
+ /* Parse constant initializer. */
942
+ /* NYI: FP constants and strings as initializers. */
943
+ static CTypeID cp_decl_constinit(CPState *cp, CType **ctp, CTypeID ctypeid)
944
+ {
945
+ CType *ctt = ctype_get(cp->cts, ctypeid);
946
+ CTInfo info;
947
+ CTSize size;
948
+ CPValue k;
949
+ CTypeID constid;
950
+ while (ctype_isattrib(ctt->info)) { /* Skip attributes. */
951
+ ctypeid = ctype_cid(ctt->info); /* Update ID, too. */
952
+ ctt = ctype_get(cp->cts, ctypeid);
953
+ }
954
+ info = ctt->info;
955
+ size = ctt->size;
956
+ if (!ctype_isinteger(info) || !(info & CTF_CONST) || size > 4)
957
+ cp_err(cp, LJ_ERR_FFI_INVTYPE);
958
+ cp_check(cp, '=');
959
+ cp_expr_sub(cp, &k, 0);
960
+ constid = lj_ctype_new(cp->cts, ctp);
961
+ (*ctp)->info = CTINFO(CT_CONSTVAL, CTF_CONST|ctypeid);
962
+ k.u32 <<= 8*(4-size);
963
+ if ((info & CTF_UNSIGNED))
964
+ k.u32 >>= 8*(4-size);
965
+ else
966
+ k.u32 = (uint32_t)((int32_t)k.u32 >> 8*(4-size));
967
+ (*ctp)->size = k.u32;
968
+ return constid;
969
+ }
970
+
971
+ /* Parse size in parentheses as part of attribute. */
972
+ static CTSize cp_decl_sizeattr(CPState *cp)
973
+ {
974
+ CTSize sz;
975
+ uint32_t oldtmask = cp->tmask;
976
+ cp->tmask = CPNS_DEFAULT; /* Required for expression evaluator. */
977
+ cp_check(cp, '(');
978
+ sz = cp_expr_ksize(cp);
979
+ cp->tmask = oldtmask;
980
+ cp_check(cp, ')');
981
+ return sz;
982
+ }
983
+
984
+ /* Parse alignment attribute. */
985
+ static void cp_decl_align(CPState *cp, CPDecl *decl)
986
+ {
987
+ CTSize al = 4; /* Unspecified alignment is 16 bytes. */
988
+ if (cp->tok == '(') {
989
+ al = cp_decl_sizeattr(cp);
990
+ al = al ? lj_fls(al) : 0;
991
+ }
992
+ CTF_INSERT(decl->attr, ALIGN, al);
993
+ decl->attr |= CTFP_ALIGNED;
994
+ }
995
+
996
+ /* Parse GCC asm("name") redirect. */
997
+ static void cp_decl_asm(CPState *cp, CPDecl *decl)
998
+ {
999
+ UNUSED(decl);
1000
+ cp_next(cp);
1001
+ cp_check(cp, '(');
1002
+ if (cp->tok == CTOK_STRING) {
1003
+ GCstr *str = cp->str;
1004
+ while (cp_next(cp) == CTOK_STRING) {
1005
+ lj_strfmt_pushf(cp->L, "%s%s", strdata(str), strdata(cp->str));
1006
+ cp->L->top--;
1007
+ str = strV(cp->L->top);
1008
+ }
1009
+ decl->redir = str;
1010
+ }
1011
+ cp_check(cp, ')');
1012
+ }
1013
+
1014
+ /* Parse GCC __attribute__((mode(...))). */
1015
+ static void cp_decl_mode(CPState *cp, CPDecl *decl)
1016
+ {
1017
+ cp_check(cp, '(');
1018
+ if (cp->tok == CTOK_IDENT) {
1019
+ const char *s = strdata(cp->str);
1020
+ CTSize sz = 0, vlen = 0;
1021
+ if (s[0] == '_' && s[1] == '_') s += 2;
1022
+ if (*s == 'V') {
1023
+ s++;
1024
+ vlen = *s++ - '0';
1025
+ if (*s >= '0' && *s <= '9')
1026
+ vlen = vlen*10 + (*s++ - '0');
1027
+ }
1028
+ switch (*s++) {
1029
+ case 'Q': sz = 1; break;
1030
+ case 'H': sz = 2; break;
1031
+ case 'S': sz = 4; break;
1032
+ case 'D': sz = 8; break;
1033
+ case 'T': sz = 16; break;
1034
+ case 'O': sz = 32; break;
1035
+ default: goto bad_size;
1036
+ }
1037
+ if (*s == 'I' || *s == 'F') {
1038
+ CTF_INSERT(decl->attr, MSIZEP, sz);
1039
+ if (vlen) CTF_INSERT(decl->attr, VSIZEP, lj_fls(vlen*sz));
1040
+ }
1041
+ bad_size:
1042
+ cp_next(cp);
1043
+ }
1044
+ cp_check(cp, ')');
1045
+ }
1046
+
1047
+ /* Parse GCC __attribute__((...)). */
1048
+ static void cp_decl_gccattribute(CPState *cp, CPDecl *decl)
1049
+ {
1050
+ cp_next(cp);
1051
+ cp_check(cp, '(');
1052
+ cp_check(cp, '(');
1053
+ while (cp->tok != ')') {
1054
+ if (cp->tok == CTOK_IDENT) {
1055
+ GCstr *attrstr = cp->str;
1056
+ cp_next(cp);
1057
+ switch (attrstr->hash) {
1058
+ case H_(64a9208e,8ce14319): case H_(8e6331b2,95a282af): /* aligned */
1059
+ cp_decl_align(cp, decl);
1060
+ break;
1061
+ case H_(42eb47de,f0ede26c): case H_(29f48a09,cf383e0c): /* packed */
1062
+ decl->attr |= CTFP_PACKED;
1063
+ break;
1064
+ case H_(0a84eef6,8dfab04c): case H_(995cf92c,d5696591): /* mode */
1065
+ cp_decl_mode(cp, decl);
1066
+ break;
1067
+ case H_(0ab31997,2d5213fa): case H_(bf875611,200e9990): /* vector_size */
1068
+ {
1069
+ CTSize vsize = cp_decl_sizeattr(cp);
1070
+ if (vsize) CTF_INSERT(decl->attr, VSIZEP, lj_fls(vsize));
1071
+ }
1072
+ break;
1073
+ #if LJ_TARGET_X86
1074
+ case H_(5ad22db8,c689b848): case H_(439150fa,65ea78cb): /* regparm */
1075
+ CTF_INSERT(decl->fattr, REGPARM, cp_decl_sizeattr(cp));
1076
+ decl->fattr |= CTFP_CCONV;
1077
+ break;
1078
+ case H_(18fc0b98,7ff4c074): case H_(4e62abed,0a747424): /* cdecl */
1079
+ CTF_INSERT(decl->fattr, CCONV, CTCC_CDECL);
1080
+ decl->fattr |= CTFP_CCONV;
1081
+ break;
1082
+ case H_(72b2e41b,494c5a44): case H_(f2356d59,f25fc9bd): /* thiscall */
1083
+ CTF_INSERT(decl->fattr, CCONV, CTCC_THISCALL);
1084
+ decl->fattr |= CTFP_CCONV;
1085
+ break;
1086
+ case H_(0d0ffc42,ab746f88): case H_(21c54ba1,7f0ca7e3): /* fastcall */
1087
+ CTF_INSERT(decl->fattr, CCONV, CTCC_FASTCALL);
1088
+ decl->fattr |= CTFP_CCONV;
1089
+ break;
1090
+ case H_(ef76b040,9412e06a): case H_(de56697b,c750e6e1): /* stdcall */
1091
+ CTF_INSERT(decl->fattr, CCONV, CTCC_STDCALL);
1092
+ decl->fattr |= CTFP_CCONV;
1093
+ break;
1094
+ case H_(ea78b622,f234bd8e): case H_(252ffb06,8d50f34b): /* sseregparm */
1095
+ decl->fattr |= CTF_SSEREGPARM;
1096
+ decl->fattr |= CTFP_CCONV;
1097
+ break;
1098
+ #endif
1099
+ default: /* Skip all other attributes. */
1100
+ goto skip_attr;
1101
+ }
1102
+ } else if (cp->tok >= CTOK_FIRSTDECL) { /* For __attribute((const)) etc. */
1103
+ cp_next(cp);
1104
+ skip_attr:
1105
+ if (cp_opt(cp, '(')) {
1106
+ while (cp->tok != ')' && cp->tok != CTOK_EOF) cp_next(cp);
1107
+ cp_check(cp, ')');
1108
+ }
1109
+ } else {
1110
+ break;
1111
+ }
1112
+ if (!cp_opt(cp, ',')) break;
1113
+ }
1114
+ cp_check(cp, ')');
1115
+ cp_check(cp, ')');
1116
+ }
1117
+
1118
+ /* Parse MSVC __declspec(...). */
1119
+ static void cp_decl_msvcattribute(CPState *cp, CPDecl *decl)
1120
+ {
1121
+ cp_next(cp);
1122
+ cp_check(cp, '(');
1123
+ while (cp->tok == CTOK_IDENT) {
1124
+ GCstr *attrstr = cp->str;
1125
+ cp_next(cp);
1126
+ switch (attrstr->hash) {
1127
+ case H_(bc2395fa,98f267f8): /* align */
1128
+ cp_decl_align(cp, decl);
1129
+ break;
1130
+ default: /* Ignore all other attributes. */
1131
+ if (cp_opt(cp, '(')) {
1132
+ while (cp->tok != ')' && cp->tok != CTOK_EOF) cp_next(cp);
1133
+ cp_check(cp, ')');
1134
+ }
1135
+ break;
1136
+ }
1137
+ }
1138
+ cp_check(cp, ')');
1139
+ }
1140
+
1141
+ /* Parse declaration attributes (and common qualifiers). */
1142
+ static void cp_decl_attributes(CPState *cp, CPDecl *decl)
1143
+ {
1144
+ for (;;) {
1145
+ switch (cp->tok) {
1146
+ case CTOK_CONST: decl->attr |= CTF_CONST; break;
1147
+ case CTOK_VOLATILE: decl->attr |= CTF_VOLATILE; break;
1148
+ case CTOK_RESTRICT: break; /* Ignore. */
1149
+ case CTOK_EXTENSION: break; /* Ignore. */
1150
+ case CTOK_ATTRIBUTE: cp_decl_gccattribute(cp, decl); continue;
1151
+ case CTOK_ASM: cp_decl_asm(cp, decl); continue;
1152
+ case CTOK_DECLSPEC: cp_decl_msvcattribute(cp, decl); continue;
1153
+ case CTOK_CCDECL:
1154
+ #if LJ_TARGET_X86
1155
+ CTF_INSERT(decl->fattr, CCONV, cp->ct->size);
1156
+ decl->fattr |= CTFP_CCONV;
1157
+ #endif
1158
+ break;
1159
+ case CTOK_PTRSZ:
1160
+ #if LJ_64
1161
+ CTF_INSERT(decl->attr, MSIZEP, cp->ct->size);
1162
+ #endif
1163
+ break;
1164
+ default: return;
1165
+ }
1166
+ cp_next(cp);
1167
+ }
1168
+ }
1169
+
1170
+ /* Parse struct/union/enum name. */
1171
+ static CTypeID cp_struct_name(CPState *cp, CPDecl *sdecl, CTInfo info)
1172
+ {
1173
+ CTypeID sid;
1174
+ CType *ct;
1175
+ cp->tmask = CPNS_STRUCT;
1176
+ cp_next(cp);
1177
+ cp_decl_attributes(cp, sdecl);
1178
+ cp->tmask = CPNS_DEFAULT;
1179
+ if (cp->tok != '{') {
1180
+ if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT);
1181
+ if (cp->val.id) { /* Name of existing struct/union/enum. */
1182
+ sid = cp->val.id;
1183
+ ct = cp->ct;
1184
+ if ((ct->info ^ info) & (CTMASK_NUM|CTF_UNION)) /* Wrong type. */
1185
+ cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(gco2str(gcref(ct->name))));
1186
+ } else { /* Create named, incomplete struct/union/enum. */
1187
+ if ((cp->mode & CPARSE_MODE_NOIMPLICIT))
1188
+ cp_errmsg(cp, 0, LJ_ERR_FFI_BADTAG, strdata(cp->str));
1189
+ sid = lj_ctype_new(cp->cts, &ct);
1190
+ ct->info = info;
1191
+ ct->size = CTSIZE_INVALID;
1192
+ ctype_setname(ct, cp->str);
1193
+ lj_ctype_addname(cp->cts, ct, sid);
1194
+ }
1195
+ cp_next(cp);
1196
+ } else { /* Create anonymous, incomplete struct/union/enum. */
1197
+ sid = lj_ctype_new(cp->cts, &ct);
1198
+ ct->info = info;
1199
+ ct->size = CTSIZE_INVALID;
1200
+ }
1201
+ if (cp->tok == '{') {
1202
+ if (ct->size != CTSIZE_INVALID || ct->sib)
1203
+ cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(gco2str(gcref(ct->name))));
1204
+ ct->sib = 1; /* Indicate the type is currently being defined. */
1205
+ }
1206
+ return sid;
1207
+ }
1208
+
1209
+ /* Determine field alignment. */
1210
+ static CTSize cp_field_align(CPState *cp, CType *ct, CTInfo info)
1211
+ {
1212
+ CTSize align = ctype_align(info);
1213
+ UNUSED(cp); UNUSED(ct);
1214
+ #if (LJ_TARGET_X86 && !LJ_ABI_WIN) || (LJ_TARGET_ARM && __APPLE__)
1215
+ /* The SYSV i386 and iOS ABIs limit alignment of non-vector fields to 2^2. */
1216
+ if (align > 2 && !(info & CTFP_ALIGNED)) {
1217
+ if (ctype_isarray(info) && !(info & CTF_VECTOR)) {
1218
+ do {
1219
+ ct = ctype_rawchild(cp->cts, ct);
1220
+ info = ct->info;
1221
+ } while (ctype_isarray(info) && !(info & CTF_VECTOR));
1222
+ }
1223
+ if (ctype_isnum(info) || ctype_isenum(info))
1224
+ align = 2;
1225
+ }
1226
+ #endif
1227
+ return align;
1228
+ }
1229
+
1230
+ /* Layout struct/union fields. */
1231
+ static void cp_struct_layout(CPState *cp, CTypeID sid, CTInfo sattr)
1232
+ {
1233
+ CTSize bofs = 0, bmaxofs = 0; /* Bit offset and max. bit offset. */
1234
+ CTSize maxalign = ctype_align(sattr);
1235
+ CType *sct = ctype_get(cp->cts, sid);
1236
+ CTInfo sinfo = sct->info;
1237
+ CTypeID fieldid = sct->sib;
1238
+ while (fieldid) {
1239
+ CType *ct = ctype_get(cp->cts, fieldid);
1240
+ CTInfo attr = ct->size; /* Field declaration attributes (temp.). */
1241
+
1242
+ if (ctype_isfield(ct->info) ||
1243
+ (ctype_isxattrib(ct->info, CTA_SUBTYPE) && attr)) {
1244
+ CTSize align, amask; /* Alignment (pow2) and alignment mask (bits). */
1245
+ CTSize sz;
1246
+ CTInfo info = lj_ctype_info(cp->cts, ctype_cid(ct->info), &sz);
1247
+ CTSize bsz, csz = 8*sz; /* Field size and container size (in bits). */
1248
+ sinfo |= (info & (CTF_QUAL|CTF_VLA)); /* Merge pseudo-qualifiers. */
1249
+
1250
+ /* Check for size overflow and determine alignment. */
1251
+ if (sz >= 0x20000000u || bofs + csz < bofs || (info & CTF_VLA)) {
1252
+ if (!(sz == CTSIZE_INVALID && ctype_isarray(info) &&
1253
+ !(sinfo & CTF_UNION)))
1254
+ cp_err(cp, LJ_ERR_FFI_INVSIZE);
1255
+ csz = sz = 0; /* Treat a[] and a[?] as zero-sized. */
1256
+ }
1257
+ align = cp_field_align(cp, ct, info);
1258
+ if (((attr|sattr) & CTFP_PACKED) ||
1259
+ ((attr & CTFP_ALIGNED) && ctype_align(attr) > align))
1260
+ align = ctype_align(attr);
1261
+ if (cp->packstack[cp->curpack] < align)
1262
+ align = cp->packstack[cp->curpack];
1263
+ if (align > maxalign) maxalign = align;
1264
+ amask = (8u << align) - 1;
1265
+
1266
+ bsz = ctype_bitcsz(ct->info); /* Bitfield size (temp.). */
1267
+ if (bsz == CTBSZ_FIELD || !ctype_isfield(ct->info)) {
1268
+ bsz = csz; /* Regular fields or subtypes always fill the container. */
1269
+ bofs = (bofs + amask) & ~amask; /* Start new aligned field. */
1270
+ ct->size = (bofs >> 3); /* Store field offset. */
1271
+ } else { /* Bitfield. */
1272
+ if (bsz == 0 || (attr & CTFP_ALIGNED) ||
1273
+ (!((attr|sattr) & CTFP_PACKED) && (bofs & amask) + bsz > csz))
1274
+ bofs = (bofs + amask) & ~amask; /* Start new aligned field. */
1275
+
1276
+ /* Prefer regular field over bitfield. */
1277
+ if (bsz == csz && (bofs & amask) == 0) {
1278
+ ct->info = CTINFO(CT_FIELD, ctype_cid(ct->info));
1279
+ ct->size = (bofs >> 3); /* Store field offset. */
1280
+ } else {
1281
+ ct->info = CTINFO(CT_BITFIELD,
1282
+ (info & (CTF_QUAL|CTF_UNSIGNED|CTF_BOOL)) +
1283
+ (csz << (CTSHIFT_BITCSZ-3)) + (bsz << CTSHIFT_BITBSZ));
1284
+ #if LJ_BE
1285
+ ct->info += ((csz - (bofs & (csz-1)) - bsz) << CTSHIFT_BITPOS);
1286
+ #else
1287
+ ct->info += ((bofs & (csz-1)) << CTSHIFT_BITPOS);
1288
+ #endif
1289
+ ct->size = ((bofs & ~(csz-1)) >> 3); /* Store container offset. */
1290
+ }
1291
+ }
1292
+
1293
+ /* Determine next offset or max. offset. */
1294
+ if ((sinfo & CTF_UNION)) {
1295
+ if (bsz > bmaxofs) bmaxofs = bsz;
1296
+ } else {
1297
+ bofs += bsz;
1298
+ }
1299
+ } /* All other fields in the chain are already set up. */
1300
+
1301
+ fieldid = ct->sib;
1302
+ }
1303
+
1304
+ /* Complete struct/union. */
1305
+ sct->info = sinfo + CTALIGN(maxalign);
1306
+ bofs = (sinfo & CTF_UNION) ? bmaxofs : bofs;
1307
+ maxalign = (8u << maxalign) - 1;
1308
+ sct->size = (((bofs + maxalign) & ~maxalign) >> 3);
1309
+ }
1310
+
1311
+ /* Parse struct/union declaration. */
1312
+ static CTypeID cp_decl_struct(CPState *cp, CPDecl *sdecl, CTInfo sinfo)
1313
+ {
1314
+ CTypeID sid = cp_struct_name(cp, sdecl, sinfo);
1315
+ if (cp_opt(cp, '{')) { /* Struct/union definition. */
1316
+ CTypeID lastid = sid;
1317
+ int lastdecl = 0;
1318
+ while (cp->tok != '}') {
1319
+ CPDecl decl;
1320
+ CPscl scl = cp_decl_spec(cp, &decl, CDF_STATIC);
1321
+ decl.mode = scl ? CPARSE_MODE_DIRECT :
1322
+ CPARSE_MODE_DIRECT|CPARSE_MODE_ABSTRACT|CPARSE_MODE_FIELD;
1323
+
1324
+ for (;;) {
1325
+ CTypeID ctypeid;
1326
+
1327
+ if (lastdecl) cp_err_token(cp, '}');
1328
+
1329
+ /* Parse field declarator. */
1330
+ decl.bits = CTSIZE_INVALID;
1331
+ cp_declarator(cp, &decl);
1332
+ ctypeid = cp_decl_intern(cp, &decl);
1333
+
1334
+ if ((scl & CDF_STATIC)) { /* Static constant in struct namespace. */
1335
+ CType *ct;
1336
+ CTypeID fieldid = cp_decl_constinit(cp, &ct, ctypeid);
1337
+ ctype_get(cp->cts, lastid)->sib = fieldid;
1338
+ lastid = fieldid;
1339
+ ctype_setname(ct, decl.name);
1340
+ } else {
1341
+ CTSize bsz = CTBSZ_FIELD; /* Temp. for layout phase. */
1342
+ CType *ct;
1343
+ CTypeID fieldid = lj_ctype_new(cp->cts, &ct); /* Do this first. */
1344
+ CType *tct = ctype_raw(cp->cts, ctypeid);
1345
+
1346
+ if (decl.bits == CTSIZE_INVALID) { /* Regular field. */
1347
+ if (ctype_isarray(tct->info) && tct->size == CTSIZE_INVALID)
1348
+ lastdecl = 1; /* a[] or a[?] must be the last declared field. */
1349
+
1350
+ /* Accept transparent struct/union/enum. */
1351
+ if (!decl.name) {
1352
+ if (!((ctype_isstruct(tct->info) && !(tct->info & CTF_VLA)) ||
1353
+ ctype_isenum(tct->info)))
1354
+ cp_err_token(cp, CTOK_IDENT);
1355
+ ct->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_SUBTYPE) + ctypeid);
1356
+ ct->size = ctype_isstruct(tct->info) ?
1357
+ (decl.attr|0x80000000u) : 0; /* For layout phase. */
1358
+ goto add_field;
1359
+ }
1360
+ } else { /* Bitfield. */
1361
+ bsz = decl.bits;
1362
+ if (!ctype_isinteger_or_bool(tct->info) ||
1363
+ (bsz == 0 && decl.name) || 8*tct->size > CTBSZ_MAX ||
1364
+ bsz > ((tct->info & CTF_BOOL) ? 1 : 8*tct->size))
1365
+ cp_errmsg(cp, ':', LJ_ERR_BADVAL);
1366
+ }
1367
+
1368
+ /* Create temporary field for layout phase. */
1369
+ ct->info = CTINFO(CT_FIELD, ctypeid + (bsz << CTSHIFT_BITCSZ));
1370
+ ct->size = decl.attr;
1371
+ if (decl.name) ctype_setname(ct, decl.name);
1372
+
1373
+ add_field:
1374
+ ctype_get(cp->cts, lastid)->sib = fieldid;
1375
+ lastid = fieldid;
1376
+ }
1377
+ if (!cp_opt(cp, ',')) break;
1378
+ cp_decl_reset(&decl);
1379
+ }
1380
+ cp_check(cp, ';');
1381
+ }
1382
+ cp_check(cp, '}');
1383
+ ctype_get(cp->cts, lastid)->sib = 0; /* Drop sib = 1 for empty structs. */
1384
+ cp_decl_attributes(cp, sdecl); /* Layout phase needs postfix attributes. */
1385
+ cp_struct_layout(cp, sid, sdecl->attr);
1386
+ }
1387
+ return sid;
1388
+ }
1389
+
1390
+ /* Parse enum declaration. */
1391
+ static CTypeID cp_decl_enum(CPState *cp, CPDecl *sdecl)
1392
+ {
1393
+ CTypeID eid = cp_struct_name(cp, sdecl, CTINFO(CT_ENUM, CTID_VOID));
1394
+ CTInfo einfo = CTINFO(CT_ENUM, CTALIGN(2) + CTID_UINT32);
1395
+ CTSize esize = 4; /* Only 32 bit enums are supported. */
1396
+ if (cp_opt(cp, '{')) { /* Enum definition. */
1397
+ CPValue k;
1398
+ CTypeID lastid = eid;
1399
+ k.u32 = 0;
1400
+ k.id = CTID_INT32;
1401
+ do {
1402
+ GCstr *name = cp->str;
1403
+ if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT);
1404
+ if (cp->val.id) cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(name));
1405
+ cp_next(cp);
1406
+ if (cp_opt(cp, '=')) {
1407
+ cp_expr_kint(cp, &k);
1408
+ if (k.id == CTID_UINT32) {
1409
+ /* C99 says that enum constants are always (signed) integers.
1410
+ ** But since unsigned constants like 0x80000000 are quite common,
1411
+ ** those are left as uint32_t.
1412
+ */
1413
+ if (k.i32 >= 0) k.id = CTID_INT32;
1414
+ } else {
1415
+ /* OTOH it's common practice and even mandated by some ABIs
1416
+ ** that the enum type itself is unsigned, unless there are any
1417
+ ** negative constants.
1418
+ */
1419
+ k.id = CTID_INT32;
1420
+ if (k.i32 < 0) einfo = CTINFO(CT_ENUM, CTALIGN(2) + CTID_INT32);
1421
+ }
1422
+ }
1423
+ /* Add named enum constant. */
1424
+ {
1425
+ CType *ct;
1426
+ CTypeID constid = lj_ctype_new(cp->cts, &ct);
1427
+ ctype_get(cp->cts, lastid)->sib = constid;
1428
+ lastid = constid;
1429
+ ctype_setname(ct, name);
1430
+ ct->info = CTINFO(CT_CONSTVAL, CTF_CONST|k.id);
1431
+ ct->size = k.u32++;
1432
+ if (k.u32 == 0x80000000u) k.id = CTID_UINT32;
1433
+ lj_ctype_addname(cp->cts, ct, constid);
1434
+ }
1435
+ if (!cp_opt(cp, ',')) break;
1436
+ } while (cp->tok != '}'); /* Trailing ',' is ok. */
1437
+ cp_check(cp, '}');
1438
+ /* Complete enum. */
1439
+ ctype_get(cp->cts, eid)->info = einfo;
1440
+ ctype_get(cp->cts, eid)->size = esize;
1441
+ }
1442
+ return eid;
1443
+ }
1444
+
1445
+ /* Parse declaration specifiers. */
1446
+ static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl)
1447
+ {
1448
+ uint32_t cds = 0, sz = 0;
1449
+ CTypeID tdef = 0;
1450
+
1451
+ decl->cp = cp;
1452
+ decl->mode = cp->mode;
1453
+ decl->name = NULL;
1454
+ decl->redir = NULL;
1455
+ decl->attr = 0;
1456
+ decl->fattr = 0;
1457
+ decl->pos = decl->top = 0;
1458
+ decl->stack[0].next = 0;
1459
+
1460
+ for (;;) { /* Parse basic types. */
1461
+ cp_decl_attributes(cp, decl);
1462
+ if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECLFLAG) {
1463
+ uint32_t cbit;
1464
+ if (cp->ct->size) {
1465
+ if (sz) goto end_decl;
1466
+ sz = cp->ct->size;
1467
+ }
1468
+ cbit = (1u << (cp->tok - CTOK_FIRSTDECL));
1469
+ cds = cds | cbit | ((cbit & cds & CDF_LONG) << 1);
1470
+ if (cp->tok >= CTOK_FIRSTSCL) {
1471
+ if (!(scl & cbit)) cp_errmsg(cp, cp->tok, LJ_ERR_FFI_BADSCL);
1472
+ } else if (tdef) {
1473
+ goto end_decl;
1474
+ }
1475
+ cp_next(cp);
1476
+ continue;
1477
+ }
1478
+ if (sz || tdef ||
1479
+ (cds & (CDF_SHORT|CDF_LONG|CDF_SIGNED|CDF_UNSIGNED|CDF_COMPLEX)))
1480
+ break;
1481
+ switch (cp->tok) {
1482
+ case CTOK_STRUCT:
1483
+ tdef = cp_decl_struct(cp, decl, CTINFO(CT_STRUCT, 0));
1484
+ continue;
1485
+ case CTOK_UNION:
1486
+ tdef = cp_decl_struct(cp, decl, CTINFO(CT_STRUCT, CTF_UNION));
1487
+ continue;
1488
+ case CTOK_ENUM:
1489
+ tdef = cp_decl_enum(cp, decl);
1490
+ continue;
1491
+ case CTOK_IDENT:
1492
+ if (ctype_istypedef(cp->ct->info)) {
1493
+ tdef = ctype_cid(cp->ct->info); /* Get typedef. */
1494
+ cp_next(cp);
1495
+ continue;
1496
+ }
1497
+ break;
1498
+ case '$':
1499
+ tdef = cp->val.id;
1500
+ cp_next(cp);
1501
+ continue;
1502
+ default:
1503
+ break;
1504
+ }
1505
+ break;
1506
+ }
1507
+ end_decl:
1508
+
1509
+ if ((cds & CDF_COMPLEX)) /* Use predefined complex types. */
1510
+ tdef = sz == 4 ? CTID_COMPLEX_FLOAT : CTID_COMPLEX_DOUBLE;
1511
+
1512
+ if (tdef) {
1513
+ cp_push_type(decl, tdef);
1514
+ } else if ((cds & CDF_VOID)) {
1515
+ cp_push(decl, CTINFO(CT_VOID, (decl->attr & CTF_QUAL)), CTSIZE_INVALID);
1516
+ decl->attr &= ~CTF_QUAL;
1517
+ } else {
1518
+ /* Determine type info and size. */
1519
+ CTInfo info = CTINFO(CT_NUM, (cds & CDF_UNSIGNED) ? CTF_UNSIGNED : 0);
1520
+ if ((cds & CDF_BOOL)) {
1521
+ if ((cds & ~(CDF_SCL|CDF_BOOL|CDF_INT|CDF_SIGNED|CDF_UNSIGNED)))
1522
+ cp_errmsg(cp, 0, LJ_ERR_FFI_INVTYPE);
1523
+ info |= CTF_BOOL;
1524
+ if (!(cds & CDF_SIGNED)) info |= CTF_UNSIGNED;
1525
+ if (!sz) {
1526
+ sz = 1;
1527
+ }
1528
+ } else if ((cds & CDF_FP)) {
1529
+ info = CTINFO(CT_NUM, CTF_FP);
1530
+ if ((cds & CDF_LONG)) sz = sizeof(long double);
1531
+ } else if ((cds & CDF_CHAR)) {
1532
+ if ((cds & (CDF_CHAR|CDF_SIGNED|CDF_UNSIGNED)) == CDF_CHAR)
1533
+ info |= CTF_UCHAR; /* Handle platforms where char is unsigned. */
1534
+ } else if ((cds & CDF_SHORT)) {
1535
+ sz = sizeof(short);
1536
+ } else if ((cds & CDF_LONGLONG)) {
1537
+ sz = 8;
1538
+ } else if ((cds & CDF_LONG)) {
1539
+ info |= CTF_LONG;
1540
+ sz = sizeof(long);
1541
+ } else if (!sz) {
1542
+ if (!(cds & (CDF_SIGNED|CDF_UNSIGNED)))
1543
+ cp_errmsg(cp, cp->tok, LJ_ERR_FFI_DECLSPEC);
1544
+ sz = sizeof(int);
1545
+ }
1546
+ lua_assert(sz != 0);
1547
+ info += CTALIGN(lj_fls(sz)); /* Use natural alignment. */
1548
+ info += (decl->attr & CTF_QUAL); /* Merge qualifiers. */
1549
+ cp_push(decl, info, sz);
1550
+ decl->attr &= ~CTF_QUAL;
1551
+ }
1552
+ decl->specpos = decl->pos;
1553
+ decl->specattr = decl->attr;
1554
+ decl->specfattr = decl->fattr;
1555
+ return (cds & CDF_SCL); /* Return storage class. */
1556
+ }
1557
+
1558
+ /* Parse array declaration. */
1559
+ static void cp_decl_array(CPState *cp, CPDecl *decl)
1560
+ {
1561
+ CTInfo info = CTINFO(CT_ARRAY, 0);
1562
+ CTSize nelem = CTSIZE_INVALID; /* Default size for a[] or a[?]. */
1563
+ cp_decl_attributes(cp, decl);
1564
+ if (cp_opt(cp, '?'))
1565
+ info |= CTF_VLA; /* Create variable-length array a[?]. */
1566
+ else if (cp->tok != ']')
1567
+ nelem = cp_expr_ksize(cp);
1568
+ cp_check(cp, ']');
1569
+ cp_add(decl, info, nelem);
1570
+ }
1571
+
1572
+ /* Parse function declaration. */
1573
+ static void cp_decl_func(CPState *cp, CPDecl *fdecl)
1574
+ {
1575
+ CTSize nargs = 0;
1576
+ CTInfo info = CTINFO(CT_FUNC, 0);
1577
+ CTypeID lastid = 0, anchor = 0;
1578
+ if (cp->tok != ')') {
1579
+ do {
1580
+ CPDecl decl;
1581
+ CTypeID ctypeid, fieldid;
1582
+ CType *ct;
1583
+ if (cp_opt(cp, '.')) { /* Vararg function. */
1584
+ cp_check(cp, '.'); /* Workaround for the minimalistic lexer. */
1585
+ cp_check(cp, '.');
1586
+ info |= CTF_VARARG;
1587
+ break;
1588
+ }
1589
+ cp_decl_spec(cp, &decl, CDF_REGISTER);
1590
+ decl.mode = CPARSE_MODE_DIRECT|CPARSE_MODE_ABSTRACT;
1591
+ cp_declarator(cp, &decl);
1592
+ ctypeid = cp_decl_intern(cp, &decl);
1593
+ ct = ctype_raw(cp->cts, ctypeid);
1594
+ if (ctype_isvoid(ct->info))
1595
+ break;
1596
+ else if (ctype_isrefarray(ct->info))
1597
+ ctypeid = lj_ctype_intern(cp->cts,
1598
+ CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(ct->info)), CTSIZE_PTR);
1599
+ else if (ctype_isfunc(ct->info))
1600
+ ctypeid = lj_ctype_intern(cp->cts,
1601
+ CTINFO(CT_PTR, CTALIGN_PTR|ctypeid), CTSIZE_PTR);
1602
+ /* Add new parameter. */
1603
+ fieldid = lj_ctype_new(cp->cts, &ct);
1604
+ if (anchor)
1605
+ ctype_get(cp->cts, lastid)->sib = fieldid;
1606
+ else
1607
+ anchor = fieldid;
1608
+ lastid = fieldid;
1609
+ if (decl.name) ctype_setname(ct, decl.name);
1610
+ ct->info = CTINFO(CT_FIELD, ctypeid);
1611
+ ct->size = nargs++;
1612
+ } while (cp_opt(cp, ','));
1613
+ }
1614
+ cp_check(cp, ')');
1615
+ if (cp_opt(cp, '{')) { /* Skip function definition. */
1616
+ int level = 1;
1617
+ cp->mode |= CPARSE_MODE_SKIP;
1618
+ for (;;) {
1619
+ if (cp->tok == '{') level++;
1620
+ else if (cp->tok == '}' && --level == 0) break;
1621
+ else if (cp->tok == CTOK_EOF) cp_err_token(cp, '}');
1622
+ cp_next(cp);
1623
+ }
1624
+ cp->mode &= ~CPARSE_MODE_SKIP;
1625
+ cp->tok = ';'; /* Ok for cp_decl_multi(), error in cp_decl_single(). */
1626
+ }
1627
+ info |= (fdecl->fattr & ~CTMASK_CID);
1628
+ fdecl->fattr = 0;
1629
+ fdecl->stack[cp_add(fdecl, info, nargs)].sib = anchor;
1630
+ }
1631
+
1632
+ /* Parse declarator. */
1633
+ static void cp_declarator(CPState *cp, CPDecl *decl)
1634
+ {
1635
+ if (++cp->depth > CPARSE_MAX_DECLDEPTH) cp_err(cp, LJ_ERR_XLEVELS);
1636
+
1637
+ for (;;) { /* Head of declarator. */
1638
+ if (cp_opt(cp, '*')) { /* Pointer. */
1639
+ CTSize sz;
1640
+ CTInfo info;
1641
+ cp_decl_attributes(cp, decl);
1642
+ sz = CTSIZE_PTR;
1643
+ info = CTINFO(CT_PTR, CTALIGN_PTR);
1644
+ #if LJ_64
1645
+ if (ctype_msizeP(decl->attr) == 4) {
1646
+ sz = 4;
1647
+ info = CTINFO(CT_PTR, CTALIGN(2));
1648
+ }
1649
+ #endif
1650
+ info += (decl->attr & (CTF_QUAL|CTF_REF));
1651
+ decl->attr &= ~(CTF_QUAL|(CTMASK_MSIZEP<<CTSHIFT_MSIZEP));
1652
+ cp_push(decl, info, sz);
1653
+ } else if (cp_opt(cp, '&') || cp_opt(cp, CTOK_ANDAND)) { /* Reference. */
1654
+ decl->attr &= ~(CTF_QUAL|(CTMASK_MSIZEP<<CTSHIFT_MSIZEP));
1655
+ cp_push(decl, CTINFO_REF(0), CTSIZE_PTR);
1656
+ } else {
1657
+ break;
1658
+ }
1659
+ }
1660
+
1661
+ if (cp_opt(cp, '(')) { /* Inner declarator. */
1662
+ CPDeclIdx pos;
1663
+ cp_decl_attributes(cp, decl);
1664
+ /* Resolve ambiguity between inner declarator and 1st function parameter. */
1665
+ if ((decl->mode & CPARSE_MODE_ABSTRACT) &&
1666
+ (cp->tok == ')' || cp_istypedecl(cp))) goto func_decl;
1667
+ pos = decl->pos;
1668
+ cp_declarator(cp, decl);
1669
+ cp_check(cp, ')');
1670
+ decl->pos = pos;
1671
+ } else if (cp->tok == CTOK_IDENT) { /* Direct declarator. */
1672
+ if (!(decl->mode & CPARSE_MODE_DIRECT)) cp_err_token(cp, CTOK_EOF);
1673
+ decl->name = cp->str;
1674
+ decl->nameid = cp->val.id;
1675
+ cp_next(cp);
1676
+ } else { /* Abstract declarator. */
1677
+ if (!(decl->mode & CPARSE_MODE_ABSTRACT)) cp_err_token(cp, CTOK_IDENT);
1678
+ }
1679
+
1680
+ for (;;) { /* Tail of declarator. */
1681
+ if (cp_opt(cp, '[')) { /* Array. */
1682
+ cp_decl_array(cp, decl);
1683
+ } else if (cp_opt(cp, '(')) { /* Function. */
1684
+ func_decl:
1685
+ cp_decl_func(cp, decl);
1686
+ } else {
1687
+ break;
1688
+ }
1689
+ }
1690
+
1691
+ if ((decl->mode & CPARSE_MODE_FIELD) && cp_opt(cp, ':')) /* Field width. */
1692
+ decl->bits = cp_expr_ksize(cp);
1693
+
1694
+ /* Process postfix attributes. */
1695
+ cp_decl_attributes(cp, decl);
1696
+ cp_push_attributes(decl);
1697
+
1698
+ cp->depth--;
1699
+ }
1700
+
1701
+ /* Parse an abstract type declaration and return it's C type ID. */
1702
+ static CTypeID cp_decl_abstract(CPState *cp)
1703
+ {
1704
+ CPDecl decl;
1705
+ cp_decl_spec(cp, &decl, 0);
1706
+ decl.mode = CPARSE_MODE_ABSTRACT;
1707
+ cp_declarator(cp, &decl);
1708
+ return cp_decl_intern(cp, &decl);
1709
+ }
1710
+
1711
+ /* Handle pragmas. */
1712
+ static void cp_pragma(CPState *cp, BCLine pragmaline)
1713
+ {
1714
+ cp_next(cp);
1715
+ if (cp->tok == CTOK_IDENT &&
1716
+ cp->str->hash == H_(e79b999f,42ca3e85)) { /* pack */
1717
+ cp_next(cp);
1718
+ cp_check(cp, '(');
1719
+ if (cp->tok == CTOK_IDENT) {
1720
+ if (cp->str->hash == H_(738e923c,a1b65954)) { /* push */
1721
+ if (cp->curpack < CPARSE_MAX_PACKSTACK) {
1722
+ cp->packstack[cp->curpack+1] = cp->packstack[cp->curpack];
1723
+ cp->curpack++;
1724
+ }
1725
+ } else if (cp->str->hash == H_(6c71cf27,6c71cf27)) { /* pop */
1726
+ if (cp->curpack > 0) cp->curpack--;
1727
+ } else {
1728
+ cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
1729
+ }
1730
+ cp_next(cp);
1731
+ if (!cp_opt(cp, ',')) goto end_pack;
1732
+ }
1733
+ if (cp->tok == CTOK_INTEGER) {
1734
+ cp->packstack[cp->curpack] = cp->val.u32 ? lj_fls(cp->val.u32) : 0;
1735
+ cp_next(cp);
1736
+ } else {
1737
+ cp->packstack[cp->curpack] = 255;
1738
+ }
1739
+ end_pack:
1740
+ cp_check(cp, ')');
1741
+ } else { /* Ignore all other pragmas. */
1742
+ while (cp->tok != CTOK_EOF && cp->linenumber == pragmaline)
1743
+ cp_next(cp);
1744
+ }
1745
+ }
1746
+
1747
+ /* Parse multiple C declarations of types or extern identifiers. */
1748
+ static void cp_decl_multi(CPState *cp)
1749
+ {
1750
+ int first = 1;
1751
+ while (cp->tok != CTOK_EOF) {
1752
+ CPDecl decl;
1753
+ CPscl scl;
1754
+ if (cp_opt(cp, ';')) { /* Skip empty statements. */
1755
+ first = 0;
1756
+ continue;
1757
+ }
1758
+ if (cp->tok == '#') { /* Workaround, since we have no preprocessor, yet. */
1759
+ BCLine pragmaline = cp->linenumber;
1760
+ if (!(cp_next(cp) == CTOK_IDENT &&
1761
+ cp->str->hash == H_(f5e6b4f8,1d509107))) /* pragma */
1762
+ cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
1763
+ cp_pragma(cp, pragmaline);
1764
+ continue;
1765
+ }
1766
+ scl = cp_decl_spec(cp, &decl, CDF_TYPEDEF|CDF_EXTERN|CDF_STATIC);
1767
+ if ((cp->tok == ';' || cp->tok == CTOK_EOF) &&
1768
+ ctype_istypedef(decl.stack[0].info)) {
1769
+ CTInfo info = ctype_rawchild(cp->cts, &decl.stack[0])->info;
1770
+ if (ctype_isstruct(info) || ctype_isenum(info))
1771
+ goto decl_end; /* Accept empty declaration of struct/union/enum. */
1772
+ }
1773
+ for (;;) {
1774
+ CTypeID ctypeid;
1775
+ cp_declarator(cp, &decl);
1776
+ ctypeid = cp_decl_intern(cp, &decl);
1777
+ if (decl.name && !decl.nameid) { /* NYI: redeclarations are ignored. */
1778
+ CType *ct;
1779
+ CTypeID id;
1780
+ if ((scl & CDF_TYPEDEF)) { /* Create new typedef. */
1781
+ id = lj_ctype_new(cp->cts, &ct);
1782
+ ct->info = CTINFO(CT_TYPEDEF, ctypeid);
1783
+ goto noredir;
1784
+ } else if (ctype_isfunc(ctype_get(cp->cts, ctypeid)->info)) {
1785
+ /* Treat both static and extern function declarations as extern. */
1786
+ ct = ctype_get(cp->cts, ctypeid);
1787
+ /* We always get new anonymous functions (typedefs are copied). */
1788
+ lua_assert(gcref(ct->name) == NULL);
1789
+ id = ctypeid; /* Just name it. */
1790
+ } else if ((scl & CDF_STATIC)) { /* Accept static constants. */
1791
+ id = cp_decl_constinit(cp, &ct, ctypeid);
1792
+ goto noredir;
1793
+ } else { /* External references have extern or no storage class. */
1794
+ id = lj_ctype_new(cp->cts, &ct);
1795
+ ct->info = CTINFO(CT_EXTERN, ctypeid);
1796
+ }
1797
+ if (decl.redir) { /* Add attribute for redirected symbol name. */
1798
+ CType *cta;
1799
+ CTypeID aid = lj_ctype_new(cp->cts, &cta);
1800
+ ct = ctype_get(cp->cts, id); /* Table may have been reallocated. */
1801
+ cta->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_REDIR));
1802
+ cta->sib = ct->sib;
1803
+ ct->sib = aid;
1804
+ ctype_setname(cta, decl.redir);
1805
+ }
1806
+ noredir:
1807
+ ctype_setname(ct, decl.name);
1808
+ lj_ctype_addname(cp->cts, ct, id);
1809
+ }
1810
+ if (!cp_opt(cp, ',')) break;
1811
+ cp_decl_reset(&decl);
1812
+ }
1813
+ decl_end:
1814
+ if (cp->tok == CTOK_EOF && first) break; /* May omit ';' for 1 decl. */
1815
+ first = 0;
1816
+ cp_check(cp, ';');
1817
+ }
1818
+ }
1819
+
1820
+ /* Parse a single C type declaration. */
1821
+ static void cp_decl_single(CPState *cp)
1822
+ {
1823
+ CPDecl decl;
1824
+ cp_decl_spec(cp, &decl, 0);
1825
+ cp_declarator(cp, &decl);
1826
+ cp->val.id = cp_decl_intern(cp, &decl);
1827
+ if (cp->tok != CTOK_EOF) cp_err_token(cp, CTOK_EOF);
1828
+ }
1829
+
1830
+ #undef H_
1831
+
1832
+ /* ------------------------------------------------------------------------ */
1833
+
1834
+ /* Protected callback for C parser. */
1835
+ static TValue *cpcparser(lua_State *L, lua_CFunction dummy, void *ud)
1836
+ {
1837
+ CPState *cp = (CPState *)ud;
1838
+ UNUSED(dummy);
1839
+ cframe_errfunc(L->cframe) = -1; /* Inherit error function. */
1840
+ cp_init(cp);
1841
+ if ((cp->mode & CPARSE_MODE_MULTI))
1842
+ cp_decl_multi(cp);
1843
+ else
1844
+ cp_decl_single(cp);
1845
+ if (cp->param && cp->param != cp->L->top)
1846
+ cp_err(cp, LJ_ERR_FFI_NUMPARAM);
1847
+ lua_assert(cp->depth == 0);
1848
+ return NULL;
1849
+ }
1850
+
1851
+ /* C parser. */
1852
+ int lj_cparse(CPState *cp)
1853
+ {
1854
+ LJ_CTYPE_SAVE(cp->cts);
1855
+ int errcode = lj_vm_cpcall(cp->L, NULL, cp, cpcparser);
1856
+ if (errcode)
1857
+ LJ_CTYPE_RESTORE(cp->cts);
1858
+ cp_cleanup(cp);
1859
+ return errcode;
1860
+ }
1861
+
1862
+ #endif