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,2725 @@
1
+ /*
2
+ ** Lua parser (source code -> bytecode).
3
+ ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
4
+ **
5
+ ** Major portions taken verbatim or adapted from the Lua interpreter.
6
+ ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7
+ */
8
+
9
+ #define lj_parse_c
10
+ #define LUA_CORE
11
+
12
+ #include "lj_obj.h"
13
+ #include "lj_gc.h"
14
+ #include "lj_err.h"
15
+ #include "lj_debug.h"
16
+ #include "lj_buf.h"
17
+ #include "lj_str.h"
18
+ #include "lj_tab.h"
19
+ #include "lj_func.h"
20
+ #include "lj_state.h"
21
+ #include "lj_bc.h"
22
+ #if LJ_HASFFI
23
+ #include "lj_ctype.h"
24
+ #endif
25
+ #include "lj_strfmt.h"
26
+ #include "lj_lex.h"
27
+ #include "lj_parse.h"
28
+ #include "lj_vm.h"
29
+ #include "lj_vmevent.h"
30
+
31
+ /* -- Parser structures and definitions ----------------------------------- */
32
+
33
+ /* Expression kinds. */
34
+ typedef enum {
35
+ /* Constant expressions must be first and in this order: */
36
+ VKNIL,
37
+ VKFALSE,
38
+ VKTRUE,
39
+ VKSTR, /* sval = string value */
40
+ VKNUM, /* nval = number value */
41
+ VKLAST = VKNUM,
42
+ VKCDATA, /* nval = cdata value, not treated as a constant expression */
43
+ /* Non-constant expressions follow: */
44
+ VLOCAL, /* info = local register, aux = vstack index */
45
+ VUPVAL, /* info = upvalue index, aux = vstack index */
46
+ VGLOBAL, /* sval = string value */
47
+ VINDEXED, /* info = table register, aux = index reg/byte/string const */
48
+ VJMP, /* info = instruction PC */
49
+ VRELOCABLE, /* info = instruction PC */
50
+ VNONRELOC, /* info = result register */
51
+ VCALL, /* info = instruction PC, aux = base */
52
+ VVOID
53
+ } ExpKind;
54
+
55
+ /* Expression descriptor. */
56
+ typedef struct ExpDesc {
57
+ union {
58
+ struct {
59
+ uint32_t info; /* Primary info. */
60
+ uint32_t aux; /* Secondary info. */
61
+ } s;
62
+ TValue nval; /* Number value. */
63
+ GCstr *sval; /* String value. */
64
+ } u;
65
+ ExpKind k;
66
+ BCPos t; /* True condition jump list. */
67
+ BCPos f; /* False condition jump list. */
68
+ } ExpDesc;
69
+
70
+ /* Macros for expressions. */
71
+ #define expr_hasjump(e) ((e)->t != (e)->f)
72
+
73
+ #define expr_isk(e) ((e)->k <= VKLAST)
74
+ #define expr_isk_nojump(e) (expr_isk(e) && !expr_hasjump(e))
75
+ #define expr_isnumk(e) ((e)->k == VKNUM)
76
+ #define expr_isnumk_nojump(e) (expr_isnumk(e) && !expr_hasjump(e))
77
+ #define expr_isstrk(e) ((e)->k == VKSTR)
78
+
79
+ #define expr_numtv(e) check_exp(expr_isnumk((e)), &(e)->u.nval)
80
+ #define expr_numberV(e) numberVnum(expr_numtv((e)))
81
+
82
+ /* Initialize expression. */
83
+ static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info)
84
+ {
85
+ e->k = k;
86
+ e->u.s.info = info;
87
+ e->f = e->t = NO_JMP;
88
+ }
89
+
90
+ /* Check number constant for +-0. */
91
+ static int expr_numiszero(ExpDesc *e)
92
+ {
93
+ TValue *o = expr_numtv(e);
94
+ return tvisint(o) ? (intV(o) == 0) : tviszero(o);
95
+ }
96
+
97
+ /* Per-function linked list of scope blocks. */
98
+ typedef struct FuncScope {
99
+ struct FuncScope *prev; /* Link to outer scope. */
100
+ MSize vstart; /* Start of block-local variables. */
101
+ uint8_t nactvar; /* Number of active vars outside the scope. */
102
+ uint8_t flags; /* Scope flags. */
103
+ } FuncScope;
104
+
105
+ #define FSCOPE_LOOP 0x01 /* Scope is a (breakable) loop. */
106
+ #define FSCOPE_BREAK 0x02 /* Break used in scope. */
107
+ #define FSCOPE_GOLA 0x04 /* Goto or label used in scope. */
108
+ #define FSCOPE_UPVAL 0x08 /* Upvalue in scope. */
109
+ #define FSCOPE_NOCLOSE 0x10 /* Do not close upvalues. */
110
+
111
+ #define NAME_BREAK ((GCstr *)(uintptr_t)1)
112
+
113
+ /* Index into variable stack. */
114
+ typedef uint16_t VarIndex;
115
+ #define LJ_MAX_VSTACK (65536 - LJ_MAX_UPVAL)
116
+
117
+ /* Variable/goto/label info. */
118
+ #define VSTACK_VAR_RW 0x01 /* R/W variable. */
119
+ #define VSTACK_GOTO 0x02 /* Pending goto. */
120
+ #define VSTACK_LABEL 0x04 /* Label. */
121
+
122
+ /* Per-function state. */
123
+ typedef struct FuncState {
124
+ GCtab *kt; /* Hash table for constants. */
125
+ LexState *ls; /* Lexer state. */
126
+ lua_State *L; /* Lua state. */
127
+ FuncScope *bl; /* Current scope. */
128
+ struct FuncState *prev; /* Enclosing function. */
129
+ BCPos pc; /* Next bytecode position. */
130
+ BCPos lasttarget; /* Bytecode position of last jump target. */
131
+ BCPos jpc; /* Pending jump list to next bytecode. */
132
+ BCReg freereg; /* First free register. */
133
+ BCReg nactvar; /* Number of active local variables. */
134
+ BCReg nkn, nkgc; /* Number of lua_Number/GCobj constants */
135
+ BCLine linedefined; /* First line of the function definition. */
136
+ BCInsLine *bcbase; /* Base of bytecode stack. */
137
+ BCPos bclim; /* Limit of bytecode stack. */
138
+ MSize vbase; /* Base of variable stack for this function. */
139
+ uint8_t flags; /* Prototype flags. */
140
+ uint8_t numparams; /* Number of parameters. */
141
+ uint8_t framesize; /* Fixed frame size. */
142
+ uint8_t nuv; /* Number of upvalues */
143
+ VarIndex varmap[LJ_MAX_LOCVAR]; /* Map from register to variable idx. */
144
+ VarIndex uvmap[LJ_MAX_UPVAL]; /* Map from upvalue to variable idx. */
145
+ VarIndex uvtmp[LJ_MAX_UPVAL]; /* Temporary upvalue map. */
146
+ } FuncState;
147
+
148
+ /* Binary and unary operators. ORDER OPR */
149
+ typedef enum BinOpr {
150
+ OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, /* ORDER ARITH */
151
+ OPR_CONCAT,
152
+ OPR_NE, OPR_EQ,
153
+ OPR_LT, OPR_GE, OPR_LE, OPR_GT,
154
+ OPR_AND, OPR_OR,
155
+ OPR_NOBINOPR
156
+ } BinOpr;
157
+
158
+ LJ_STATIC_ASSERT((int)BC_ISGE-(int)BC_ISLT == (int)OPR_GE-(int)OPR_LT);
159
+ LJ_STATIC_ASSERT((int)BC_ISLE-(int)BC_ISLT == (int)OPR_LE-(int)OPR_LT);
160
+ LJ_STATIC_ASSERT((int)BC_ISGT-(int)BC_ISLT == (int)OPR_GT-(int)OPR_LT);
161
+ LJ_STATIC_ASSERT((int)BC_SUBVV-(int)BC_ADDVV == (int)OPR_SUB-(int)OPR_ADD);
162
+ LJ_STATIC_ASSERT((int)BC_MULVV-(int)BC_ADDVV == (int)OPR_MUL-(int)OPR_ADD);
163
+ LJ_STATIC_ASSERT((int)BC_DIVVV-(int)BC_ADDVV == (int)OPR_DIV-(int)OPR_ADD);
164
+ LJ_STATIC_ASSERT((int)BC_MODVV-(int)BC_ADDVV == (int)OPR_MOD-(int)OPR_ADD);
165
+
166
+ /* -- Error handling ------------------------------------------------------ */
167
+
168
+ LJ_NORET LJ_NOINLINE static void err_syntax(LexState *ls, ErrMsg em)
169
+ {
170
+ lj_lex_error(ls, ls->tok, em);
171
+ }
172
+
173
+ LJ_NORET LJ_NOINLINE static void err_token(LexState *ls, LexToken tok)
174
+ {
175
+ lj_lex_error(ls, ls->tok, LJ_ERR_XTOKEN, lj_lex_token2str(ls, tok));
176
+ }
177
+
178
+ LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what)
179
+ {
180
+ if (fs->linedefined == 0)
181
+ lj_lex_error(fs->ls, 0, LJ_ERR_XLIMM, limit, what);
182
+ else
183
+ lj_lex_error(fs->ls, 0, LJ_ERR_XLIMF, fs->linedefined, limit, what);
184
+ }
185
+
186
+ #define checklimit(fs, v, l, m) if ((v) >= (l)) err_limit(fs, l, m)
187
+ #define checklimitgt(fs, v, l, m) if ((v) > (l)) err_limit(fs, l, m)
188
+ #define checkcond(ls, c, em) { if (!(c)) err_syntax(ls, em); }
189
+
190
+ /* -- Management of constants --------------------------------------------- */
191
+
192
+ /* Return bytecode encoding for primitive constant. */
193
+ #define const_pri(e) check_exp((e)->k <= VKTRUE, (e)->k)
194
+
195
+ #define tvhaskslot(o) ((o)->u32.hi == 0)
196
+ #define tvkslot(o) ((o)->u32.lo)
197
+
198
+ /* Add a number constant. */
199
+ static BCReg const_num(FuncState *fs, ExpDesc *e)
200
+ {
201
+ lua_State *L = fs->L;
202
+ TValue *o;
203
+ lua_assert(expr_isnumk(e));
204
+ o = lj_tab_set(L, fs->kt, &e->u.nval);
205
+ if (tvhaskslot(o))
206
+ return tvkslot(o);
207
+ o->u64 = fs->nkn;
208
+ return fs->nkn++;
209
+ }
210
+
211
+ /* Add a GC object constant. */
212
+ static BCReg const_gc(FuncState *fs, GCobj *gc, uint32_t itype)
213
+ {
214
+ lua_State *L = fs->L;
215
+ TValue key, *o;
216
+ setgcV(L, &key, gc, itype);
217
+ /* NOBARRIER: the key is new or kept alive. */
218
+ o = lj_tab_set(L, fs->kt, &key);
219
+ if (tvhaskslot(o))
220
+ return tvkslot(o);
221
+ o->u64 = fs->nkgc;
222
+ return fs->nkgc++;
223
+ }
224
+
225
+ /* Add a string constant. */
226
+ static BCReg const_str(FuncState *fs, ExpDesc *e)
227
+ {
228
+ lua_assert(expr_isstrk(e) || e->k == VGLOBAL);
229
+ return const_gc(fs, obj2gco(e->u.sval), LJ_TSTR);
230
+ }
231
+
232
+ /* Anchor string constant to avoid GC. */
233
+ GCstr *lj_parse_keepstr(LexState *ls, const char *str, size_t len)
234
+ {
235
+ /* NOBARRIER: the key is new or kept alive. */
236
+ lua_State *L = ls->L;
237
+ GCstr *s = lj_str_new(L, str, len);
238
+ TValue *tv = lj_tab_setstr(L, ls->fs->kt, s);
239
+ if (tvisnil(tv)) setboolV(tv, 1);
240
+ lj_gc_check(L);
241
+ return s;
242
+ }
243
+
244
+ #if LJ_HASFFI
245
+ /* Anchor cdata to avoid GC. */
246
+ void lj_parse_keepcdata(LexState *ls, TValue *tv, GCcdata *cd)
247
+ {
248
+ /* NOBARRIER: the key is new or kept alive. */
249
+ lua_State *L = ls->L;
250
+ setcdataV(L, tv, cd);
251
+ setboolV(lj_tab_set(L, ls->fs->kt, tv), 1);
252
+ }
253
+ #endif
254
+
255
+ /* -- Jump list handling -------------------------------------------------- */
256
+
257
+ /* Get next element in jump list. */
258
+ static BCPos jmp_next(FuncState *fs, BCPos pc)
259
+ {
260
+ ptrdiff_t delta = bc_j(fs->bcbase[pc].ins);
261
+ if ((BCPos)delta == NO_JMP)
262
+ return NO_JMP;
263
+ else
264
+ return (BCPos)(((ptrdiff_t)pc+1)+delta);
265
+ }
266
+
267
+ /* Check if any of the instructions on the jump list produce no value. */
268
+ static int jmp_novalue(FuncState *fs, BCPos list)
269
+ {
270
+ for (; list != NO_JMP; list = jmp_next(fs, list)) {
271
+ BCIns p = fs->bcbase[list >= 1 ? list-1 : list].ins;
272
+ if (!(bc_op(p) == BC_ISTC || bc_op(p) == BC_ISFC || bc_a(p) == NO_REG))
273
+ return 1;
274
+ }
275
+ return 0;
276
+ }
277
+
278
+ /* Patch register of test instructions. */
279
+ static int jmp_patchtestreg(FuncState *fs, BCPos pc, BCReg reg)
280
+ {
281
+ BCInsLine *ilp = &fs->bcbase[pc >= 1 ? pc-1 : pc];
282
+ BCOp op = bc_op(ilp->ins);
283
+ if (op == BC_ISTC || op == BC_ISFC) {
284
+ if (reg != NO_REG && reg != bc_d(ilp->ins)) {
285
+ setbc_a(&ilp->ins, reg);
286
+ } else { /* Nothing to store or already in the right register. */
287
+ setbc_op(&ilp->ins, op+(BC_IST-BC_ISTC));
288
+ setbc_a(&ilp->ins, 0);
289
+ }
290
+ } else if (bc_a(ilp->ins) == NO_REG) {
291
+ if (reg == NO_REG) {
292
+ ilp->ins = BCINS_AJ(BC_JMP, bc_a(fs->bcbase[pc].ins), 0);
293
+ } else {
294
+ setbc_a(&ilp->ins, reg);
295
+ if (reg >= bc_a(ilp[1].ins))
296
+ setbc_a(&ilp[1].ins, reg+1);
297
+ }
298
+ } else {
299
+ return 0; /* Cannot patch other instructions. */
300
+ }
301
+ return 1;
302
+ }
303
+
304
+ /* Drop values for all instructions on jump list. */
305
+ static void jmp_dropval(FuncState *fs, BCPos list)
306
+ {
307
+ for (; list != NO_JMP; list = jmp_next(fs, list))
308
+ jmp_patchtestreg(fs, list, NO_REG);
309
+ }
310
+
311
+ /* Patch jump instruction to target. */
312
+ static void jmp_patchins(FuncState *fs, BCPos pc, BCPos dest)
313
+ {
314
+ BCIns *jmp = &fs->bcbase[pc].ins;
315
+ BCPos offset = dest-(pc+1)+BCBIAS_J;
316
+ lua_assert(dest != NO_JMP);
317
+ if (offset > BCMAX_D)
318
+ err_syntax(fs->ls, LJ_ERR_XJUMP);
319
+ setbc_d(jmp, offset);
320
+ }
321
+
322
+ /* Append to jump list. */
323
+ static void jmp_append(FuncState *fs, BCPos *l1, BCPos l2)
324
+ {
325
+ if (l2 == NO_JMP) {
326
+ return;
327
+ } else if (*l1 == NO_JMP) {
328
+ *l1 = l2;
329
+ } else {
330
+ BCPos list = *l1;
331
+ BCPos next;
332
+ while ((next = jmp_next(fs, list)) != NO_JMP) /* Find last element. */
333
+ list = next;
334
+ jmp_patchins(fs, list, l2);
335
+ }
336
+ }
337
+
338
+ /* Patch jump list and preserve produced values. */
339
+ static void jmp_patchval(FuncState *fs, BCPos list, BCPos vtarget,
340
+ BCReg reg, BCPos dtarget)
341
+ {
342
+ while (list != NO_JMP) {
343
+ BCPos next = jmp_next(fs, list);
344
+ if (jmp_patchtestreg(fs, list, reg))
345
+ jmp_patchins(fs, list, vtarget); /* Jump to target with value. */
346
+ else
347
+ jmp_patchins(fs, list, dtarget); /* Jump to default target. */
348
+ list = next;
349
+ }
350
+ }
351
+
352
+ /* Jump to following instruction. Append to list of pending jumps. */
353
+ static void jmp_tohere(FuncState *fs, BCPos list)
354
+ {
355
+ fs->lasttarget = fs->pc;
356
+ jmp_append(fs, &fs->jpc, list);
357
+ }
358
+
359
+ /* Patch jump list to target. */
360
+ static void jmp_patch(FuncState *fs, BCPos list, BCPos target)
361
+ {
362
+ if (target == fs->pc) {
363
+ jmp_tohere(fs, list);
364
+ } else {
365
+ lua_assert(target < fs->pc);
366
+ jmp_patchval(fs, list, target, NO_REG, target);
367
+ }
368
+ }
369
+
370
+ /* -- Bytecode register allocator ----------------------------------------- */
371
+
372
+ /* Bump frame size. */
373
+ static void bcreg_bump(FuncState *fs, BCReg n)
374
+ {
375
+ BCReg sz = fs->freereg + n;
376
+ if (sz > fs->framesize) {
377
+ if (sz >= LJ_MAX_SLOTS)
378
+ err_syntax(fs->ls, LJ_ERR_XSLOTS);
379
+ fs->framesize = (uint8_t)sz;
380
+ }
381
+ }
382
+
383
+ /* Reserve registers. */
384
+ static void bcreg_reserve(FuncState *fs, BCReg n)
385
+ {
386
+ bcreg_bump(fs, n);
387
+ fs->freereg += n;
388
+ }
389
+
390
+ /* Free register. */
391
+ static void bcreg_free(FuncState *fs, BCReg reg)
392
+ {
393
+ if (reg >= fs->nactvar) {
394
+ fs->freereg--;
395
+ lua_assert(reg == fs->freereg);
396
+ }
397
+ }
398
+
399
+ /* Free register for expression. */
400
+ static void expr_free(FuncState *fs, ExpDesc *e)
401
+ {
402
+ if (e->k == VNONRELOC)
403
+ bcreg_free(fs, e->u.s.info);
404
+ }
405
+
406
+ /* -- Bytecode emitter ---------------------------------------------------- */
407
+
408
+ /* Emit bytecode instruction. */
409
+ static BCPos bcemit_INS(FuncState *fs, BCIns ins)
410
+ {
411
+ BCPos pc = fs->pc;
412
+ LexState *ls = fs->ls;
413
+ jmp_patchval(fs, fs->jpc, pc, NO_REG, pc);
414
+ fs->jpc = NO_JMP;
415
+ if (LJ_UNLIKELY(pc >= fs->bclim)) {
416
+ ptrdiff_t base = fs->bcbase - ls->bcstack;
417
+ checklimit(fs, ls->sizebcstack, LJ_MAX_BCINS, "bytecode instructions");
418
+ lj_mem_growvec(fs->L, ls->bcstack, ls->sizebcstack, LJ_MAX_BCINS,BCInsLine);
419
+ fs->bclim = (BCPos)(ls->sizebcstack - base);
420
+ fs->bcbase = ls->bcstack + base;
421
+ }
422
+ fs->bcbase[pc].ins = ins;
423
+ fs->bcbase[pc].line = ls->lastline;
424
+ fs->pc = pc+1;
425
+ return pc;
426
+ }
427
+
428
+ #define bcemit_ABC(fs, o, a, b, c) bcemit_INS(fs, BCINS_ABC(o, a, b, c))
429
+ #define bcemit_AD(fs, o, a, d) bcemit_INS(fs, BCINS_AD(o, a, d))
430
+ #define bcemit_AJ(fs, o, a, j) bcemit_INS(fs, BCINS_AJ(o, a, j))
431
+
432
+ #define bcptr(fs, e) (&(fs)->bcbase[(e)->u.s.info].ins)
433
+
434
+ /* -- Bytecode emitter for expressions ------------------------------------ */
435
+
436
+ /* Discharge non-constant expression to any register. */
437
+ static void expr_discharge(FuncState *fs, ExpDesc *e)
438
+ {
439
+ BCIns ins;
440
+ if (e->k == VUPVAL) {
441
+ ins = BCINS_AD(BC_UGET, 0, e->u.s.info);
442
+ } else if (e->k == VGLOBAL) {
443
+ ins = BCINS_AD(BC_GGET, 0, const_str(fs, e));
444
+ } else if (e->k == VINDEXED) {
445
+ BCReg rc = e->u.s.aux;
446
+ if ((int32_t)rc < 0) {
447
+ ins = BCINS_ABC(BC_TGETS, 0, e->u.s.info, ~rc);
448
+ } else if (rc > BCMAX_C) {
449
+ ins = BCINS_ABC(BC_TGETB, 0, e->u.s.info, rc-(BCMAX_C+1));
450
+ } else {
451
+ bcreg_free(fs, rc);
452
+ ins = BCINS_ABC(BC_TGETV, 0, e->u.s.info, rc);
453
+ }
454
+ bcreg_free(fs, e->u.s.info);
455
+ } else if (e->k == VCALL) {
456
+ e->u.s.info = e->u.s.aux;
457
+ e->k = VNONRELOC;
458
+ return;
459
+ } else if (e->k == VLOCAL) {
460
+ e->k = VNONRELOC;
461
+ return;
462
+ } else {
463
+ return;
464
+ }
465
+ e->u.s.info = bcemit_INS(fs, ins);
466
+ e->k = VRELOCABLE;
467
+ }
468
+
469
+ /* Emit bytecode to set a range of registers to nil. */
470
+ static void bcemit_nil(FuncState *fs, BCReg from, BCReg n)
471
+ {
472
+ if (fs->pc > fs->lasttarget) { /* No jumps to current position? */
473
+ BCIns *ip = &fs->bcbase[fs->pc-1].ins;
474
+ BCReg pto, pfrom = bc_a(*ip);
475
+ switch (bc_op(*ip)) { /* Try to merge with the previous instruction. */
476
+ case BC_KPRI:
477
+ if (bc_d(*ip) != ~LJ_TNIL) break;
478
+ if (from == pfrom) {
479
+ if (n == 1) return;
480
+ } else if (from == pfrom+1) {
481
+ from = pfrom;
482
+ n++;
483
+ } else {
484
+ break;
485
+ }
486
+ *ip = BCINS_AD(BC_KNIL, from, from+n-1); /* Replace KPRI. */
487
+ return;
488
+ case BC_KNIL:
489
+ pto = bc_d(*ip);
490
+ if (pfrom <= from && from <= pto+1) { /* Can we connect both ranges? */
491
+ if (from+n-1 > pto)
492
+ setbc_d(ip, from+n-1); /* Patch previous instruction range. */
493
+ return;
494
+ }
495
+ break;
496
+ default:
497
+ break;
498
+ }
499
+ }
500
+ /* Emit new instruction or replace old instruction. */
501
+ bcemit_INS(fs, n == 1 ? BCINS_AD(BC_KPRI, from, VKNIL) :
502
+ BCINS_AD(BC_KNIL, from, from+n-1));
503
+ }
504
+
505
+ /* Discharge an expression to a specific register. Ignore branches. */
506
+ static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg)
507
+ {
508
+ BCIns ins;
509
+ expr_discharge(fs, e);
510
+ if (e->k == VKSTR) {
511
+ ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e));
512
+ } else if (e->k == VKNUM) {
513
+ #if LJ_DUALNUM
514
+ cTValue *tv = expr_numtv(e);
515
+ if (tvisint(tv) && checki16(intV(tv)))
516
+ ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)intV(tv));
517
+ else
518
+ #else
519
+ lua_Number n = expr_numberV(e);
520
+ int32_t k = lj_num2int(n);
521
+ if (checki16(k) && n == (lua_Number)k)
522
+ ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k);
523
+ else
524
+ #endif
525
+ ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e));
526
+ #if LJ_HASFFI
527
+ } else if (e->k == VKCDATA) {
528
+ fs->flags |= PROTO_FFI;
529
+ ins = BCINS_AD(BC_KCDATA, reg,
530
+ const_gc(fs, obj2gco(cdataV(&e->u.nval)), LJ_TCDATA));
531
+ #endif
532
+ } else if (e->k == VRELOCABLE) {
533
+ setbc_a(bcptr(fs, e), reg);
534
+ goto noins;
535
+ } else if (e->k == VNONRELOC) {
536
+ if (reg == e->u.s.info)
537
+ goto noins;
538
+ ins = BCINS_AD(BC_MOV, reg, e->u.s.info);
539
+ } else if (e->k == VKNIL) {
540
+ bcemit_nil(fs, reg, 1);
541
+ goto noins;
542
+ } else if (e->k <= VKTRUE) {
543
+ ins = BCINS_AD(BC_KPRI, reg, const_pri(e));
544
+ } else {
545
+ lua_assert(e->k == VVOID || e->k == VJMP);
546
+ return;
547
+ }
548
+ bcemit_INS(fs, ins);
549
+ noins:
550
+ e->u.s.info = reg;
551
+ e->k = VNONRELOC;
552
+ }
553
+
554
+ /* Forward declaration. */
555
+ static BCPos bcemit_jmp(FuncState *fs);
556
+
557
+ /* Discharge an expression to a specific register. */
558
+ static void expr_toreg(FuncState *fs, ExpDesc *e, BCReg reg)
559
+ {
560
+ expr_toreg_nobranch(fs, e, reg);
561
+ if (e->k == VJMP)
562
+ jmp_append(fs, &e->t, e->u.s.info); /* Add it to the true jump list. */
563
+ if (expr_hasjump(e)) { /* Discharge expression with branches. */
564
+ BCPos jend, jfalse = NO_JMP, jtrue = NO_JMP;
565
+ if (jmp_novalue(fs, e->t) || jmp_novalue(fs, e->f)) {
566
+ BCPos jval = (e->k == VJMP) ? NO_JMP : bcemit_jmp(fs);
567
+ jfalse = bcemit_AD(fs, BC_KPRI, reg, VKFALSE);
568
+ bcemit_AJ(fs, BC_JMP, fs->freereg, 1);
569
+ jtrue = bcemit_AD(fs, BC_KPRI, reg, VKTRUE);
570
+ jmp_tohere(fs, jval);
571
+ }
572
+ jend = fs->pc;
573
+ fs->lasttarget = jend;
574
+ jmp_patchval(fs, e->f, jend, reg, jfalse);
575
+ jmp_patchval(fs, e->t, jend, reg, jtrue);
576
+ }
577
+ e->f = e->t = NO_JMP;
578
+ e->u.s.info = reg;
579
+ e->k = VNONRELOC;
580
+ }
581
+
582
+ /* Discharge an expression to the next free register. */
583
+ static void expr_tonextreg(FuncState *fs, ExpDesc *e)
584
+ {
585
+ expr_discharge(fs, e);
586
+ expr_free(fs, e);
587
+ bcreg_reserve(fs, 1);
588
+ expr_toreg(fs, e, fs->freereg - 1);
589
+ }
590
+
591
+ /* Discharge an expression to any register. */
592
+ static BCReg expr_toanyreg(FuncState *fs, ExpDesc *e)
593
+ {
594
+ expr_discharge(fs, e);
595
+ if (e->k == VNONRELOC) {
596
+ if (!expr_hasjump(e)) return e->u.s.info; /* Already in a register. */
597
+ if (e->u.s.info >= fs->nactvar) {
598
+ expr_toreg(fs, e, e->u.s.info); /* Discharge to temp. register. */
599
+ return e->u.s.info;
600
+ }
601
+ }
602
+ expr_tonextreg(fs, e); /* Discharge to next register. */
603
+ return e->u.s.info;
604
+ }
605
+
606
+ /* Partially discharge expression to a value. */
607
+ static void expr_toval(FuncState *fs, ExpDesc *e)
608
+ {
609
+ if (expr_hasjump(e))
610
+ expr_toanyreg(fs, e);
611
+ else
612
+ expr_discharge(fs, e);
613
+ }
614
+
615
+ /* Emit store for LHS expression. */
616
+ static void bcemit_store(FuncState *fs, ExpDesc *var, ExpDesc *e)
617
+ {
618
+ BCIns ins;
619
+ if (var->k == VLOCAL) {
620
+ fs->ls->vstack[var->u.s.aux].info |= VSTACK_VAR_RW;
621
+ expr_free(fs, e);
622
+ expr_toreg(fs, e, var->u.s.info);
623
+ return;
624
+ } else if (var->k == VUPVAL) {
625
+ fs->ls->vstack[var->u.s.aux].info |= VSTACK_VAR_RW;
626
+ expr_toval(fs, e);
627
+ if (e->k <= VKTRUE)
628
+ ins = BCINS_AD(BC_USETP, var->u.s.info, const_pri(e));
629
+ else if (e->k == VKSTR)
630
+ ins = BCINS_AD(BC_USETS, var->u.s.info, const_str(fs, e));
631
+ else if (e->k == VKNUM)
632
+ ins = BCINS_AD(BC_USETN, var->u.s.info, const_num(fs, e));
633
+ else
634
+ ins = BCINS_AD(BC_USETV, var->u.s.info, expr_toanyreg(fs, e));
635
+ } else if (var->k == VGLOBAL) {
636
+ BCReg ra = expr_toanyreg(fs, e);
637
+ ins = BCINS_AD(BC_GSET, ra, const_str(fs, var));
638
+ } else {
639
+ BCReg ra, rc;
640
+ lua_assert(var->k == VINDEXED);
641
+ ra = expr_toanyreg(fs, e);
642
+ rc = var->u.s.aux;
643
+ if ((int32_t)rc < 0) {
644
+ ins = BCINS_ABC(BC_TSETS, ra, var->u.s.info, ~rc);
645
+ } else if (rc > BCMAX_C) {
646
+ ins = BCINS_ABC(BC_TSETB, ra, var->u.s.info, rc-(BCMAX_C+1));
647
+ } else {
648
+ /* Free late alloced key reg to avoid assert on free of value reg. */
649
+ /* This can only happen when called from expr_table(). */
650
+ lua_assert(e->k != VNONRELOC || ra < fs->nactvar ||
651
+ rc < ra || (bcreg_free(fs, rc),1));
652
+ ins = BCINS_ABC(BC_TSETV, ra, var->u.s.info, rc);
653
+ }
654
+ }
655
+ bcemit_INS(fs, ins);
656
+ expr_free(fs, e);
657
+ }
658
+
659
+ /* Emit method lookup expression. */
660
+ static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key)
661
+ {
662
+ BCReg idx, func, obj = expr_toanyreg(fs, e);
663
+ expr_free(fs, e);
664
+ func = fs->freereg;
665
+ bcemit_AD(fs, BC_MOV, func+1+LJ_FR2, obj); /* Copy object to 1st argument. */
666
+ lua_assert(expr_isstrk(key));
667
+ idx = const_str(fs, key);
668
+ if (idx <= BCMAX_C) {
669
+ bcreg_reserve(fs, 2+LJ_FR2);
670
+ bcemit_ABC(fs, BC_TGETS, func, obj, idx);
671
+ } else {
672
+ bcreg_reserve(fs, 3+LJ_FR2);
673
+ bcemit_AD(fs, BC_KSTR, func+2+LJ_FR2, idx);
674
+ bcemit_ABC(fs, BC_TGETV, func, obj, func+2+LJ_FR2);
675
+ fs->freereg--;
676
+ }
677
+ e->u.s.info = func;
678
+ e->k = VNONRELOC;
679
+ }
680
+
681
+ /* -- Bytecode emitter for branches --------------------------------------- */
682
+
683
+ /* Emit unconditional branch. */
684
+ static BCPos bcemit_jmp(FuncState *fs)
685
+ {
686
+ BCPos jpc = fs->jpc;
687
+ BCPos j = fs->pc - 1;
688
+ BCIns *ip = &fs->bcbase[j].ins;
689
+ fs->jpc = NO_JMP;
690
+ if ((int32_t)j >= (int32_t)fs->lasttarget && bc_op(*ip) == BC_UCLO) {
691
+ setbc_j(ip, NO_JMP);
692
+ fs->lasttarget = j+1;
693
+ } else {
694
+ j = bcemit_AJ(fs, BC_JMP, fs->freereg, NO_JMP);
695
+ }
696
+ jmp_append(fs, &j, jpc);
697
+ return j;
698
+ }
699
+
700
+ /* Invert branch condition of bytecode instruction. */
701
+ static void invertcond(FuncState *fs, ExpDesc *e)
702
+ {
703
+ BCIns *ip = &fs->bcbase[e->u.s.info - 1].ins;
704
+ setbc_op(ip, bc_op(*ip)^1);
705
+ }
706
+
707
+ /* Emit conditional branch. */
708
+ static BCPos bcemit_branch(FuncState *fs, ExpDesc *e, int cond)
709
+ {
710
+ BCPos pc;
711
+ if (e->k == VRELOCABLE) {
712
+ BCIns *ip = bcptr(fs, e);
713
+ if (bc_op(*ip) == BC_NOT) {
714
+ *ip = BCINS_AD(cond ? BC_ISF : BC_IST, 0, bc_d(*ip));
715
+ return bcemit_jmp(fs);
716
+ }
717
+ }
718
+ if (e->k != VNONRELOC) {
719
+ bcreg_reserve(fs, 1);
720
+ expr_toreg_nobranch(fs, e, fs->freereg-1);
721
+ }
722
+ bcemit_AD(fs, cond ? BC_ISTC : BC_ISFC, NO_REG, e->u.s.info);
723
+ pc = bcemit_jmp(fs);
724
+ expr_free(fs, e);
725
+ return pc;
726
+ }
727
+
728
+ /* Emit branch on true condition. */
729
+ static void bcemit_branch_t(FuncState *fs, ExpDesc *e)
730
+ {
731
+ BCPos pc;
732
+ expr_discharge(fs, e);
733
+ if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE)
734
+ pc = NO_JMP; /* Never jump. */
735
+ else if (e->k == VJMP)
736
+ invertcond(fs, e), pc = e->u.s.info;
737
+ else if (e->k == VKFALSE || e->k == VKNIL)
738
+ expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs);
739
+ else
740
+ pc = bcemit_branch(fs, e, 0);
741
+ jmp_append(fs, &e->f, pc);
742
+ jmp_tohere(fs, e->t);
743
+ e->t = NO_JMP;
744
+ }
745
+
746
+ /* Emit branch on false condition. */
747
+ static void bcemit_branch_f(FuncState *fs, ExpDesc *e)
748
+ {
749
+ BCPos pc;
750
+ expr_discharge(fs, e);
751
+ if (e->k == VKNIL || e->k == VKFALSE)
752
+ pc = NO_JMP; /* Never jump. */
753
+ else if (e->k == VJMP)
754
+ pc = e->u.s.info;
755
+ else if (e->k == VKSTR || e->k == VKNUM || e->k == VKTRUE)
756
+ expr_toreg_nobranch(fs, e, NO_REG), pc = bcemit_jmp(fs);
757
+ else
758
+ pc = bcemit_branch(fs, e, 1);
759
+ jmp_append(fs, &e->t, pc);
760
+ jmp_tohere(fs, e->f);
761
+ e->f = NO_JMP;
762
+ }
763
+
764
+ /* -- Bytecode emitter for operators -------------------------------------- */
765
+
766
+ /* Try constant-folding of arithmetic operators. */
767
+ static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2)
768
+ {
769
+ TValue o;
770
+ lua_Number n;
771
+ if (!expr_isnumk_nojump(e1) || !expr_isnumk_nojump(e2)) return 0;
772
+ n = lj_vm_foldarith(expr_numberV(e1), expr_numberV(e2), (int)opr-OPR_ADD);
773
+ setnumV(&o, n);
774
+ if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */
775
+ if (LJ_DUALNUM) {
776
+ int32_t k = lj_num2int(n);
777
+ if ((lua_Number)k == n) {
778
+ setintV(&e1->u.nval, k);
779
+ return 1;
780
+ }
781
+ }
782
+ setnumV(&e1->u.nval, n);
783
+ return 1;
784
+ }
785
+
786
+ /* Emit arithmetic operator. */
787
+ static void bcemit_arith(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2)
788
+ {
789
+ BCReg rb, rc, t;
790
+ uint32_t op;
791
+ if (foldarith(opr, e1, e2))
792
+ return;
793
+ if (opr == OPR_POW) {
794
+ op = BC_POW;
795
+ rc = expr_toanyreg(fs, e2);
796
+ rb = expr_toanyreg(fs, e1);
797
+ } else {
798
+ op = opr-OPR_ADD+BC_ADDVV;
799
+ /* Must discharge 2nd operand first since VINDEXED might free regs. */
800
+ expr_toval(fs, e2);
801
+ if (expr_isnumk(e2) && (rc = const_num(fs, e2)) <= BCMAX_C)
802
+ op -= BC_ADDVV-BC_ADDVN;
803
+ else
804
+ rc = expr_toanyreg(fs, e2);
805
+ /* 1st operand discharged by bcemit_binop_left, but need KNUM/KSHORT. */
806
+ lua_assert(expr_isnumk(e1) || e1->k == VNONRELOC);
807
+ expr_toval(fs, e1);
808
+ /* Avoid two consts to satisfy bytecode constraints. */
809
+ if (expr_isnumk(e1) && !expr_isnumk(e2) &&
810
+ (t = const_num(fs, e1)) <= BCMAX_B) {
811
+ rb = rc; rc = t; op -= BC_ADDVV-BC_ADDNV;
812
+ } else {
813
+ rb = expr_toanyreg(fs, e1);
814
+ }
815
+ }
816
+ /* Using expr_free might cause asserts if the order is wrong. */
817
+ if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--;
818
+ if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--;
819
+ e1->u.s.info = bcemit_ABC(fs, op, 0, rb, rc);
820
+ e1->k = VRELOCABLE;
821
+ }
822
+
823
+ /* Emit comparison operator. */
824
+ static void bcemit_comp(FuncState *fs, BinOpr opr, ExpDesc *e1, ExpDesc *e2)
825
+ {
826
+ ExpDesc *eret = e1;
827
+ BCIns ins;
828
+ expr_toval(fs, e1);
829
+ if (opr == OPR_EQ || opr == OPR_NE) {
830
+ BCOp op = opr == OPR_EQ ? BC_ISEQV : BC_ISNEV;
831
+ BCReg ra;
832
+ if (expr_isk(e1)) { e1 = e2; e2 = eret; } /* Need constant in 2nd arg. */
833
+ ra = expr_toanyreg(fs, e1); /* First arg must be in a reg. */
834
+ expr_toval(fs, e2);
835
+ switch (e2->k) {
836
+ case VKNIL: case VKFALSE: case VKTRUE:
837
+ ins = BCINS_AD(op+(BC_ISEQP-BC_ISEQV), ra, const_pri(e2));
838
+ break;
839
+ case VKSTR:
840
+ ins = BCINS_AD(op+(BC_ISEQS-BC_ISEQV), ra, const_str(fs, e2));
841
+ break;
842
+ case VKNUM:
843
+ ins = BCINS_AD(op+(BC_ISEQN-BC_ISEQV), ra, const_num(fs, e2));
844
+ break;
845
+ default:
846
+ ins = BCINS_AD(op, ra, expr_toanyreg(fs, e2));
847
+ break;
848
+ }
849
+ } else {
850
+ uint32_t op = opr-OPR_LT+BC_ISLT;
851
+ BCReg ra, rd;
852
+ if ((op-BC_ISLT) & 1) { /* GT -> LT, GE -> LE */
853
+ e1 = e2; e2 = eret; /* Swap operands. */
854
+ op = ((op-BC_ISLT)^3)+BC_ISLT;
855
+ expr_toval(fs, e1);
856
+ }
857
+ rd = expr_toanyreg(fs, e2);
858
+ ra = expr_toanyreg(fs, e1);
859
+ ins = BCINS_AD(op, ra, rd);
860
+ }
861
+ /* Using expr_free might cause asserts if the order is wrong. */
862
+ if (e1->k == VNONRELOC && e1->u.s.info >= fs->nactvar) fs->freereg--;
863
+ if (e2->k == VNONRELOC && e2->u.s.info >= fs->nactvar) fs->freereg--;
864
+ bcemit_INS(fs, ins);
865
+ eret->u.s.info = bcemit_jmp(fs);
866
+ eret->k = VJMP;
867
+ }
868
+
869
+ /* Fixup left side of binary operator. */
870
+ static void bcemit_binop_left(FuncState *fs, BinOpr op, ExpDesc *e)
871
+ {
872
+ if (op == OPR_AND) {
873
+ bcemit_branch_t(fs, e);
874
+ } else if (op == OPR_OR) {
875
+ bcemit_branch_f(fs, e);
876
+ } else if (op == OPR_CONCAT) {
877
+ expr_tonextreg(fs, e);
878
+ } else if (op == OPR_EQ || op == OPR_NE) {
879
+ if (!expr_isk_nojump(e)) expr_toanyreg(fs, e);
880
+ } else {
881
+ if (!expr_isnumk_nojump(e)) expr_toanyreg(fs, e);
882
+ }
883
+ }
884
+
885
+ /* Emit binary operator. */
886
+ static void bcemit_binop(FuncState *fs, BinOpr op, ExpDesc *e1, ExpDesc *e2)
887
+ {
888
+ if (op <= OPR_POW) {
889
+ bcemit_arith(fs, op, e1, e2);
890
+ } else if (op == OPR_AND) {
891
+ lua_assert(e1->t == NO_JMP); /* List must be closed. */
892
+ expr_discharge(fs, e2);
893
+ jmp_append(fs, &e2->f, e1->f);
894
+ *e1 = *e2;
895
+ } else if (op == OPR_OR) {
896
+ lua_assert(e1->f == NO_JMP); /* List must be closed. */
897
+ expr_discharge(fs, e2);
898
+ jmp_append(fs, &e2->t, e1->t);
899
+ *e1 = *e2;
900
+ } else if (op == OPR_CONCAT) {
901
+ expr_toval(fs, e2);
902
+ if (e2->k == VRELOCABLE && bc_op(*bcptr(fs, e2)) == BC_CAT) {
903
+ lua_assert(e1->u.s.info == bc_b(*bcptr(fs, e2))-1);
904
+ expr_free(fs, e1);
905
+ setbc_b(bcptr(fs, e2), e1->u.s.info);
906
+ e1->u.s.info = e2->u.s.info;
907
+ } else {
908
+ expr_tonextreg(fs, e2);
909
+ expr_free(fs, e2);
910
+ expr_free(fs, e1);
911
+ e1->u.s.info = bcemit_ABC(fs, BC_CAT, 0, e1->u.s.info, e2->u.s.info);
912
+ }
913
+ e1->k = VRELOCABLE;
914
+ } else {
915
+ lua_assert(op == OPR_NE || op == OPR_EQ ||
916
+ op == OPR_LT || op == OPR_GE || op == OPR_LE || op == OPR_GT);
917
+ bcemit_comp(fs, op, e1, e2);
918
+ }
919
+ }
920
+
921
+ /* Emit unary operator. */
922
+ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
923
+ {
924
+ if (op == BC_NOT) {
925
+ /* Swap true and false lists. */
926
+ { BCPos temp = e->f; e->f = e->t; e->t = temp; }
927
+ jmp_dropval(fs, e->f);
928
+ jmp_dropval(fs, e->t);
929
+ expr_discharge(fs, e);
930
+ if (e->k == VKNIL || e->k == VKFALSE) {
931
+ e->k = VKTRUE;
932
+ return;
933
+ } else if (expr_isk(e) || (LJ_HASFFI && e->k == VKCDATA)) {
934
+ e->k = VKFALSE;
935
+ return;
936
+ } else if (e->k == VJMP) {
937
+ invertcond(fs, e);
938
+ return;
939
+ } else if (e->k == VRELOCABLE) {
940
+ bcreg_reserve(fs, 1);
941
+ setbc_a(bcptr(fs, e), fs->freereg-1);
942
+ e->u.s.info = fs->freereg-1;
943
+ e->k = VNONRELOC;
944
+ } else {
945
+ lua_assert(e->k == VNONRELOC);
946
+ }
947
+ } else {
948
+ lua_assert(op == BC_UNM || op == BC_LEN);
949
+ if (op == BC_UNM && !expr_hasjump(e)) { /* Constant-fold negations. */
950
+ #if LJ_HASFFI
951
+ if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */
952
+ GCcdata *cd = cdataV(&e->u.nval);
953
+ int64_t *p = (int64_t *)cdataptr(cd);
954
+ if (cd->ctypeid == CTID_COMPLEX_DOUBLE)
955
+ p[1] ^= (int64_t)U64x(80000000,00000000);
956
+ else
957
+ *p = -*p;
958
+ return;
959
+ } else
960
+ #endif
961
+ if (expr_isnumk(e) && !expr_numiszero(e)) { /* Avoid folding to -0. */
962
+ TValue *o = expr_numtv(e);
963
+ if (tvisint(o)) {
964
+ int32_t k = intV(o);
965
+ if (k == -k)
966
+ setnumV(o, -(lua_Number)k);
967
+ else
968
+ setintV(o, -k);
969
+ return;
970
+ } else {
971
+ o->u64 ^= U64x(80000000,00000000);
972
+ return;
973
+ }
974
+ }
975
+ }
976
+ expr_toanyreg(fs, e);
977
+ }
978
+ expr_free(fs, e);
979
+ e->u.s.info = bcemit_AD(fs, op, 0, e->u.s.info);
980
+ e->k = VRELOCABLE;
981
+ }
982
+
983
+ /* -- Lexer support ------------------------------------------------------- */
984
+
985
+ /* Check and consume optional token. */
986
+ static int lex_opt(LexState *ls, LexToken tok)
987
+ {
988
+ if (ls->tok == tok) {
989
+ lj_lex_next(ls);
990
+ return 1;
991
+ }
992
+ return 0;
993
+ }
994
+
995
+ /* Check and consume token. */
996
+ static void lex_check(LexState *ls, LexToken tok)
997
+ {
998
+ if (ls->tok != tok)
999
+ err_token(ls, tok);
1000
+ lj_lex_next(ls);
1001
+ }
1002
+
1003
+ /* Check for matching token. */
1004
+ static void lex_match(LexState *ls, LexToken what, LexToken who, BCLine line)
1005
+ {
1006
+ if (!lex_opt(ls, what)) {
1007
+ if (line == ls->linenumber) {
1008
+ err_token(ls, what);
1009
+ } else {
1010
+ const char *swhat = lj_lex_token2str(ls, what);
1011
+ const char *swho = lj_lex_token2str(ls, who);
1012
+ lj_lex_error(ls, ls->tok, LJ_ERR_XMATCH, swhat, swho, line);
1013
+ }
1014
+ }
1015
+ }
1016
+
1017
+ /* Check for string token. */
1018
+ static GCstr *lex_str(LexState *ls)
1019
+ {
1020
+ GCstr *s;
1021
+ if (ls->tok != TK_name && (LJ_52 || ls->tok != TK_goto))
1022
+ err_token(ls, TK_name);
1023
+ s = strV(&ls->tokval);
1024
+ lj_lex_next(ls);
1025
+ return s;
1026
+ }
1027
+
1028
+ /* -- Variable handling --------------------------------------------------- */
1029
+
1030
+ #define var_get(ls, fs, i) ((ls)->vstack[(fs)->varmap[(i)]])
1031
+
1032
+ /* Define a new local variable. */
1033
+ static void var_new(LexState *ls, BCReg n, GCstr *name)
1034
+ {
1035
+ FuncState *fs = ls->fs;
1036
+ MSize vtop = ls->vtop;
1037
+ checklimit(fs, fs->nactvar+n, LJ_MAX_LOCVAR, "local variables");
1038
+ if (LJ_UNLIKELY(vtop >= ls->sizevstack)) {
1039
+ if (ls->sizevstack >= LJ_MAX_VSTACK)
1040
+ lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK);
1041
+ lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo);
1042
+ }
1043
+ lua_assert((uintptr_t)name < VARNAME__MAX ||
1044
+ lj_tab_getstr(fs->kt, name) != NULL);
1045
+ /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */
1046
+ setgcref(ls->vstack[vtop].name, obj2gco(name));
1047
+ fs->varmap[fs->nactvar+n] = (uint16_t)vtop;
1048
+ ls->vtop = vtop+1;
1049
+ }
1050
+
1051
+ #define var_new_lit(ls, n, v) \
1052
+ var_new(ls, (n), lj_parse_keepstr(ls, "" v, sizeof(v)-1))
1053
+
1054
+ #define var_new_fixed(ls, n, vn) \
1055
+ var_new(ls, (n), (GCstr *)(uintptr_t)(vn))
1056
+
1057
+ /* Add local variables. */
1058
+ static void var_add(LexState *ls, BCReg nvars)
1059
+ {
1060
+ FuncState *fs = ls->fs;
1061
+ BCReg nactvar = fs->nactvar;
1062
+ while (nvars--) {
1063
+ VarInfo *v = &var_get(ls, fs, nactvar);
1064
+ v->startpc = fs->pc;
1065
+ v->slot = nactvar++;
1066
+ v->info = 0;
1067
+ }
1068
+ fs->nactvar = nactvar;
1069
+ }
1070
+
1071
+ /* Remove local variables. */
1072
+ static void var_remove(LexState *ls, BCReg tolevel)
1073
+ {
1074
+ FuncState *fs = ls->fs;
1075
+ while (fs->nactvar > tolevel)
1076
+ var_get(ls, fs, --fs->nactvar).endpc = fs->pc;
1077
+ }
1078
+
1079
+ /* Lookup local variable name. */
1080
+ static BCReg var_lookup_local(FuncState *fs, GCstr *n)
1081
+ {
1082
+ int i;
1083
+ for (i = fs->nactvar-1; i >= 0; i--) {
1084
+ if (n == strref(var_get(fs->ls, fs, i).name))
1085
+ return (BCReg)i;
1086
+ }
1087
+ return (BCReg)-1; /* Not found. */
1088
+ }
1089
+
1090
+ /* Lookup or add upvalue index. */
1091
+ static MSize var_lookup_uv(FuncState *fs, MSize vidx, ExpDesc *e)
1092
+ {
1093
+ MSize i, n = fs->nuv;
1094
+ for (i = 0; i < n; i++)
1095
+ if (fs->uvmap[i] == vidx)
1096
+ return i; /* Already exists. */
1097
+ /* Otherwise create a new one. */
1098
+ checklimit(fs, fs->nuv, LJ_MAX_UPVAL, "upvalues");
1099
+ lua_assert(e->k == VLOCAL || e->k == VUPVAL);
1100
+ fs->uvmap[n] = (uint16_t)vidx;
1101
+ fs->uvtmp[n] = (uint16_t)(e->k == VLOCAL ? vidx : LJ_MAX_VSTACK+e->u.s.info);
1102
+ fs->nuv = n+1;
1103
+ return n;
1104
+ }
1105
+
1106
+ /* Forward declaration. */
1107
+ static void fscope_uvmark(FuncState *fs, BCReg level);
1108
+
1109
+ /* Recursively lookup variables in enclosing functions. */
1110
+ static MSize var_lookup_(FuncState *fs, GCstr *name, ExpDesc *e, int first)
1111
+ {
1112
+ if (fs) {
1113
+ BCReg reg = var_lookup_local(fs, name);
1114
+ if ((int32_t)reg >= 0) { /* Local in this function? */
1115
+ expr_init(e, VLOCAL, reg);
1116
+ if (!first)
1117
+ fscope_uvmark(fs, reg); /* Scope now has an upvalue. */
1118
+ return (MSize)(e->u.s.aux = (uint32_t)fs->varmap[reg]);
1119
+ } else {
1120
+ MSize vidx = var_lookup_(fs->prev, name, e, 0); /* Var in outer func? */
1121
+ if ((int32_t)vidx >= 0) { /* Yes, make it an upvalue here. */
1122
+ e->u.s.info = (uint8_t)var_lookup_uv(fs, vidx, e);
1123
+ e->k = VUPVAL;
1124
+ return vidx;
1125
+ }
1126
+ }
1127
+ } else { /* Not found in any function, must be a global. */
1128
+ expr_init(e, VGLOBAL, 0);
1129
+ e->u.sval = name;
1130
+ }
1131
+ return (MSize)-1; /* Global. */
1132
+ }
1133
+
1134
+ /* Lookup variable name. */
1135
+ #define var_lookup(ls, e) \
1136
+ var_lookup_((ls)->fs, lex_str(ls), (e), 1)
1137
+
1138
+ /* -- Goto an label handling ---------------------------------------------- */
1139
+
1140
+ /* Add a new goto or label. */
1141
+ static MSize gola_new(LexState *ls, GCstr *name, uint8_t info, BCPos pc)
1142
+ {
1143
+ FuncState *fs = ls->fs;
1144
+ MSize vtop = ls->vtop;
1145
+ if (LJ_UNLIKELY(vtop >= ls->sizevstack)) {
1146
+ if (ls->sizevstack >= LJ_MAX_VSTACK)
1147
+ lj_lex_error(ls, 0, LJ_ERR_XLIMC, LJ_MAX_VSTACK);
1148
+ lj_mem_growvec(ls->L, ls->vstack, ls->sizevstack, LJ_MAX_VSTACK, VarInfo);
1149
+ }
1150
+ lua_assert(name == NAME_BREAK || lj_tab_getstr(fs->kt, name) != NULL);
1151
+ /* NOBARRIER: name is anchored in fs->kt and ls->vstack is not a GCobj. */
1152
+ setgcref(ls->vstack[vtop].name, obj2gco(name));
1153
+ ls->vstack[vtop].startpc = pc;
1154
+ ls->vstack[vtop].slot = (uint8_t)fs->nactvar;
1155
+ ls->vstack[vtop].info = info;
1156
+ ls->vtop = vtop+1;
1157
+ return vtop;
1158
+ }
1159
+
1160
+ #define gola_isgoto(v) ((v)->info & VSTACK_GOTO)
1161
+ #define gola_islabel(v) ((v)->info & VSTACK_LABEL)
1162
+ #define gola_isgotolabel(v) ((v)->info & (VSTACK_GOTO|VSTACK_LABEL))
1163
+
1164
+ /* Patch goto to jump to label. */
1165
+ static void gola_patch(LexState *ls, VarInfo *vg, VarInfo *vl)
1166
+ {
1167
+ FuncState *fs = ls->fs;
1168
+ BCPos pc = vg->startpc;
1169
+ setgcrefnull(vg->name); /* Invalidate pending goto. */
1170
+ setbc_a(&fs->bcbase[pc].ins, vl->slot);
1171
+ jmp_patch(fs, pc, vl->startpc);
1172
+ }
1173
+
1174
+ /* Patch goto to close upvalues. */
1175
+ static void gola_close(LexState *ls, VarInfo *vg)
1176
+ {
1177
+ FuncState *fs = ls->fs;
1178
+ BCPos pc = vg->startpc;
1179
+ BCIns *ip = &fs->bcbase[pc].ins;
1180
+ lua_assert(gola_isgoto(vg));
1181
+ lua_assert(bc_op(*ip) == BC_JMP || bc_op(*ip) == BC_UCLO);
1182
+ setbc_a(ip, vg->slot);
1183
+ if (bc_op(*ip) == BC_JMP) {
1184
+ BCPos next = jmp_next(fs, pc);
1185
+ if (next != NO_JMP) jmp_patch(fs, next, pc); /* Jump to UCLO. */
1186
+ setbc_op(ip, BC_UCLO); /* Turn into UCLO. */
1187
+ setbc_j(ip, NO_JMP);
1188
+ }
1189
+ }
1190
+
1191
+ /* Resolve pending forward gotos for label. */
1192
+ static void gola_resolve(LexState *ls, FuncScope *bl, MSize idx)
1193
+ {
1194
+ VarInfo *vg = ls->vstack + bl->vstart;
1195
+ VarInfo *vl = ls->vstack + idx;
1196
+ for (; vg < vl; vg++)
1197
+ if (gcrefeq(vg->name, vl->name) && gola_isgoto(vg)) {
1198
+ if (vg->slot < vl->slot) {
1199
+ GCstr *name = strref(var_get(ls, ls->fs, vg->slot).name);
1200
+ lua_assert((uintptr_t)name >= VARNAME__MAX);
1201
+ ls->linenumber = ls->fs->bcbase[vg->startpc].line;
1202
+ lua_assert(strref(vg->name) != NAME_BREAK);
1203
+ lj_lex_error(ls, 0, LJ_ERR_XGSCOPE,
1204
+ strdata(strref(vg->name)), strdata(name));
1205
+ }
1206
+ gola_patch(ls, vg, vl);
1207
+ }
1208
+ }
1209
+
1210
+ /* Fixup remaining gotos and labels for scope. */
1211
+ static void gola_fixup(LexState *ls, FuncScope *bl)
1212
+ {
1213
+ VarInfo *v = ls->vstack + bl->vstart;
1214
+ VarInfo *ve = ls->vstack + ls->vtop;
1215
+ for (; v < ve; v++) {
1216
+ GCstr *name = strref(v->name);
1217
+ if (name != NULL) { /* Only consider remaining valid gotos/labels. */
1218
+ if (gola_islabel(v)) {
1219
+ VarInfo *vg;
1220
+ setgcrefnull(v->name); /* Invalidate label that goes out of scope. */
1221
+ for (vg = v+1; vg < ve; vg++) /* Resolve pending backward gotos. */
1222
+ if (strref(vg->name) == name && gola_isgoto(vg)) {
1223
+ if ((bl->flags&FSCOPE_UPVAL) && vg->slot > v->slot)
1224
+ gola_close(ls, vg);
1225
+ gola_patch(ls, vg, v);
1226
+ }
1227
+ } else if (gola_isgoto(v)) {
1228
+ if (bl->prev) { /* Propagate goto or break to outer scope. */
1229
+ bl->prev->flags |= name == NAME_BREAK ? FSCOPE_BREAK : FSCOPE_GOLA;
1230
+ v->slot = bl->nactvar;
1231
+ if ((bl->flags & FSCOPE_UPVAL))
1232
+ gola_close(ls, v);
1233
+ } else { /* No outer scope: undefined goto label or no loop. */
1234
+ ls->linenumber = ls->fs->bcbase[v->startpc].line;
1235
+ if (name == NAME_BREAK)
1236
+ lj_lex_error(ls, 0, LJ_ERR_XBREAK);
1237
+ else
1238
+ lj_lex_error(ls, 0, LJ_ERR_XLUNDEF, strdata(name));
1239
+ }
1240
+ }
1241
+ }
1242
+ }
1243
+ }
1244
+
1245
+ /* Find existing label. */
1246
+ static VarInfo *gola_findlabel(LexState *ls, GCstr *name)
1247
+ {
1248
+ VarInfo *v = ls->vstack + ls->fs->bl->vstart;
1249
+ VarInfo *ve = ls->vstack + ls->vtop;
1250
+ for (; v < ve; v++)
1251
+ if (strref(v->name) == name && gola_islabel(v))
1252
+ return v;
1253
+ return NULL;
1254
+ }
1255
+
1256
+ /* -- Scope handling ------------------------------------------------------ */
1257
+
1258
+ /* Begin a scope. */
1259
+ static void fscope_begin(FuncState *fs, FuncScope *bl, int flags)
1260
+ {
1261
+ bl->nactvar = (uint8_t)fs->nactvar;
1262
+ bl->flags = flags;
1263
+ bl->vstart = fs->ls->vtop;
1264
+ bl->prev = fs->bl;
1265
+ fs->bl = bl;
1266
+ lua_assert(fs->freereg == fs->nactvar);
1267
+ }
1268
+
1269
+ /* End a scope. */
1270
+ static void fscope_end(FuncState *fs)
1271
+ {
1272
+ FuncScope *bl = fs->bl;
1273
+ LexState *ls = fs->ls;
1274
+ fs->bl = bl->prev;
1275
+ var_remove(ls, bl->nactvar);
1276
+ fs->freereg = fs->nactvar;
1277
+ lua_assert(bl->nactvar == fs->nactvar);
1278
+ if ((bl->flags & (FSCOPE_UPVAL|FSCOPE_NOCLOSE)) == FSCOPE_UPVAL)
1279
+ bcemit_AJ(fs, BC_UCLO, bl->nactvar, 0);
1280
+ if ((bl->flags & FSCOPE_BREAK)) {
1281
+ if ((bl->flags & FSCOPE_LOOP)) {
1282
+ MSize idx = gola_new(ls, NAME_BREAK, VSTACK_LABEL, fs->pc);
1283
+ ls->vtop = idx; /* Drop break label immediately. */
1284
+ gola_resolve(ls, bl, idx);
1285
+ return;
1286
+ } /* else: need the fixup step to propagate the breaks. */
1287
+ } else if (!(bl->flags & FSCOPE_GOLA)) {
1288
+ return;
1289
+ }
1290
+ gola_fixup(ls, bl);
1291
+ }
1292
+
1293
+ /* Mark scope as having an upvalue. */
1294
+ static void fscope_uvmark(FuncState *fs, BCReg level)
1295
+ {
1296
+ FuncScope *bl;
1297
+ for (bl = fs->bl; bl && bl->nactvar > level; bl = bl->prev)
1298
+ ;
1299
+ if (bl)
1300
+ bl->flags |= FSCOPE_UPVAL;
1301
+ }
1302
+
1303
+ /* -- Function state management ------------------------------------------- */
1304
+
1305
+ /* Fixup bytecode for prototype. */
1306
+ static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, MSize n)
1307
+ {
1308
+ BCInsLine *base = fs->bcbase;
1309
+ MSize i;
1310
+ pt->sizebc = n;
1311
+ bc[0] = BCINS_AD((fs->flags & PROTO_VARARG) ? BC_FUNCV : BC_FUNCF,
1312
+ fs->framesize, 0);
1313
+ for (i = 1; i < n; i++)
1314
+ bc[i] = base[i].ins;
1315
+ }
1316
+
1317
+ /* Fixup upvalues for child prototype, step #2. */
1318
+ static void fs_fixup_uv2(FuncState *fs, GCproto *pt)
1319
+ {
1320
+ VarInfo *vstack = fs->ls->vstack;
1321
+ uint16_t *uv = proto_uv(pt);
1322
+ MSize i, n = pt->sizeuv;
1323
+ for (i = 0; i < n; i++) {
1324
+ VarIndex vidx = uv[i];
1325
+ if (vidx >= LJ_MAX_VSTACK)
1326
+ uv[i] = vidx - LJ_MAX_VSTACK;
1327
+ else if ((vstack[vidx].info & VSTACK_VAR_RW))
1328
+ uv[i] = vstack[vidx].slot | PROTO_UV_LOCAL;
1329
+ else
1330
+ uv[i] = vstack[vidx].slot | PROTO_UV_LOCAL | PROTO_UV_IMMUTABLE;
1331
+ }
1332
+ }
1333
+
1334
+ /* Fixup constants for prototype. */
1335
+ static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr)
1336
+ {
1337
+ GCtab *kt;
1338
+ TValue *array;
1339
+ Node *node;
1340
+ MSize i, hmask;
1341
+ checklimitgt(fs, fs->nkn, BCMAX_D+1, "constants");
1342
+ checklimitgt(fs, fs->nkgc, BCMAX_D+1, "constants");
1343
+ setmref(pt->k, kptr);
1344
+ pt->sizekn = fs->nkn;
1345
+ pt->sizekgc = fs->nkgc;
1346
+ kt = fs->kt;
1347
+ array = tvref(kt->array);
1348
+ for (i = 0; i < kt->asize; i++)
1349
+ if (tvhaskslot(&array[i])) {
1350
+ TValue *tv = &((TValue *)kptr)[tvkslot(&array[i])];
1351
+ if (LJ_DUALNUM)
1352
+ setintV(tv, (int32_t)i);
1353
+ else
1354
+ setnumV(tv, (lua_Number)i);
1355
+ }
1356
+ node = noderef(kt->node);
1357
+ hmask = kt->hmask;
1358
+ for (i = 0; i <= hmask; i++) {
1359
+ Node *n = &node[i];
1360
+ if (tvhaskslot(&n->val)) {
1361
+ ptrdiff_t kidx = (ptrdiff_t)tvkslot(&n->val);
1362
+ lua_assert(!tvisint(&n->key));
1363
+ if (tvisnum(&n->key)) {
1364
+ TValue *tv = &((TValue *)kptr)[kidx];
1365
+ if (LJ_DUALNUM) {
1366
+ lua_Number nn = numV(&n->key);
1367
+ int32_t k = lj_num2int(nn);
1368
+ lua_assert(!tvismzero(&n->key));
1369
+ if ((lua_Number)k == nn)
1370
+ setintV(tv, k);
1371
+ else
1372
+ *tv = n->key;
1373
+ } else {
1374
+ *tv = n->key;
1375
+ }
1376
+ } else {
1377
+ GCobj *o = gcV(&n->key);
1378
+ setgcref(((GCRef *)kptr)[~kidx], o);
1379
+ lj_gc_objbarrier(fs->L, pt, o);
1380
+ if (tvisproto(&n->key))
1381
+ fs_fixup_uv2(fs, gco2pt(o));
1382
+ }
1383
+ }
1384
+ }
1385
+ }
1386
+
1387
+ /* Fixup upvalues for prototype, step #1. */
1388
+ static void fs_fixup_uv1(FuncState *fs, GCproto *pt, uint16_t *uv)
1389
+ {
1390
+ setmref(pt->uv, uv);
1391
+ pt->sizeuv = fs->nuv;
1392
+ memcpy(uv, fs->uvtmp, fs->nuv*sizeof(VarIndex));
1393
+ }
1394
+
1395
+ #ifndef LUAJIT_DISABLE_DEBUGINFO
1396
+ /* Prepare lineinfo for prototype. */
1397
+ static size_t fs_prep_line(FuncState *fs, BCLine numline)
1398
+ {
1399
+ return (fs->pc-1) << (numline < 256 ? 0 : numline < 65536 ? 1 : 2);
1400
+ }
1401
+
1402
+ /* Fixup lineinfo for prototype. */
1403
+ static void fs_fixup_line(FuncState *fs, GCproto *pt,
1404
+ void *lineinfo, BCLine numline)
1405
+ {
1406
+ BCInsLine *base = fs->bcbase + 1;
1407
+ BCLine first = fs->linedefined;
1408
+ MSize i = 0, n = fs->pc-1;
1409
+ pt->firstline = fs->linedefined;
1410
+ pt->numline = numline;
1411
+ setmref(pt->lineinfo, lineinfo);
1412
+ if (LJ_LIKELY(numline < 256)) {
1413
+ uint8_t *li = (uint8_t *)lineinfo;
1414
+ do {
1415
+ BCLine delta = base[i].line - first;
1416
+ lua_assert(delta >= 0 && delta < 256);
1417
+ li[i] = (uint8_t)delta;
1418
+ } while (++i < n);
1419
+ } else if (LJ_LIKELY(numline < 65536)) {
1420
+ uint16_t *li = (uint16_t *)lineinfo;
1421
+ do {
1422
+ BCLine delta = base[i].line - first;
1423
+ lua_assert(delta >= 0 && delta < 65536);
1424
+ li[i] = (uint16_t)delta;
1425
+ } while (++i < n);
1426
+ } else {
1427
+ uint32_t *li = (uint32_t *)lineinfo;
1428
+ do {
1429
+ BCLine delta = base[i].line - first;
1430
+ lua_assert(delta >= 0);
1431
+ li[i] = (uint32_t)delta;
1432
+ } while (++i < n);
1433
+ }
1434
+ }
1435
+
1436
+ /* Prepare variable info for prototype. */
1437
+ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
1438
+ {
1439
+ VarInfo *vs =ls->vstack, *ve;
1440
+ MSize i, n;
1441
+ BCPos lastpc;
1442
+ lj_buf_reset(&ls->sb); /* Copy to temp. string buffer. */
1443
+ /* Store upvalue names. */
1444
+ for (i = 0, n = fs->nuv; i < n; i++) {
1445
+ GCstr *s = strref(vs[fs->uvmap[i]].name);
1446
+ MSize len = s->len+1;
1447
+ char *p = lj_buf_more(&ls->sb, len);
1448
+ p = lj_buf_wmem(p, strdata(s), len);
1449
+ setsbufP(&ls->sb, p);
1450
+ }
1451
+ *ofsvar = sbuflen(&ls->sb);
1452
+ lastpc = 0;
1453
+ /* Store local variable names and compressed ranges. */
1454
+ for (ve = vs + ls->vtop, vs += fs->vbase; vs < ve; vs++) {
1455
+ if (!gola_isgotolabel(vs)) {
1456
+ GCstr *s = strref(vs->name);
1457
+ BCPos startpc;
1458
+ char *p;
1459
+ if ((uintptr_t)s < VARNAME__MAX) {
1460
+ p = lj_buf_more(&ls->sb, 1 + 2*5);
1461
+ *p++ = (char)(uintptr_t)s;
1462
+ } else {
1463
+ MSize len = s->len+1;
1464
+ p = lj_buf_more(&ls->sb, len + 2*5);
1465
+ p = lj_buf_wmem(p, strdata(s), len);
1466
+ }
1467
+ startpc = vs->startpc;
1468
+ p = lj_strfmt_wuleb128(p, startpc-lastpc);
1469
+ p = lj_strfmt_wuleb128(p, vs->endpc-startpc);
1470
+ setsbufP(&ls->sb, p);
1471
+ lastpc = startpc;
1472
+ }
1473
+ }
1474
+ lj_buf_putb(&ls->sb, '\0'); /* Terminator for varinfo. */
1475
+ return sbuflen(&ls->sb);
1476
+ }
1477
+
1478
+ /* Fixup variable info for prototype. */
1479
+ static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar)
1480
+ {
1481
+ setmref(pt->uvinfo, p);
1482
+ setmref(pt->varinfo, (char *)p + ofsvar);
1483
+ memcpy(p, sbufB(&ls->sb), sbuflen(&ls->sb)); /* Copy from temp. buffer. */
1484
+ }
1485
+ #else
1486
+
1487
+ /* Initialize with empty debug info, if disabled. */
1488
+ #define fs_prep_line(fs, numline) (UNUSED(numline), 0)
1489
+ #define fs_fixup_line(fs, pt, li, numline) \
1490
+ pt->firstline = pt->numline = 0, setmref((pt)->lineinfo, NULL)
1491
+ #define fs_prep_var(ls, fs, ofsvar) (UNUSED(ofsvar), 0)
1492
+ #define fs_fixup_var(ls, pt, p, ofsvar) \
1493
+ setmref((pt)->uvinfo, NULL), setmref((pt)->varinfo, NULL)
1494
+
1495
+ #endif
1496
+
1497
+ /* Check if bytecode op returns. */
1498
+ static int bcopisret(BCOp op)
1499
+ {
1500
+ switch (op) {
1501
+ case BC_CALLMT: case BC_CALLT:
1502
+ case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1:
1503
+ return 1;
1504
+ default:
1505
+ return 0;
1506
+ }
1507
+ }
1508
+
1509
+ /* Fixup return instruction for prototype. */
1510
+ static void fs_fixup_ret(FuncState *fs)
1511
+ {
1512
+ BCPos lastpc = fs->pc;
1513
+ if (lastpc <= fs->lasttarget || !bcopisret(bc_op(fs->bcbase[lastpc-1].ins))) {
1514
+ if ((fs->bl->flags & FSCOPE_UPVAL))
1515
+ bcemit_AJ(fs, BC_UCLO, 0, 0);
1516
+ bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */
1517
+ }
1518
+ fs->bl->flags |= FSCOPE_NOCLOSE; /* Handled above. */
1519
+ fscope_end(fs);
1520
+ lua_assert(fs->bl == NULL);
1521
+ /* May need to fixup returns encoded before first function was created. */
1522
+ if (fs->flags & PROTO_FIXUP_RETURN) {
1523
+ BCPos pc;
1524
+ for (pc = 1; pc < lastpc; pc++) {
1525
+ BCIns ins = fs->bcbase[pc].ins;
1526
+ BCPos offset;
1527
+ switch (bc_op(ins)) {
1528
+ case BC_CALLMT: case BC_CALLT:
1529
+ case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1:
1530
+ offset = bcemit_INS(fs, ins); /* Copy original instruction. */
1531
+ fs->bcbase[offset].line = fs->bcbase[pc].line;
1532
+ offset = offset-(pc+1)+BCBIAS_J;
1533
+ if (offset > BCMAX_D)
1534
+ err_syntax(fs->ls, LJ_ERR_XFIXUP);
1535
+ /* Replace with UCLO plus branch. */
1536
+ fs->bcbase[pc].ins = BCINS_AD(BC_UCLO, 0, offset);
1537
+ break;
1538
+ case BC_UCLO:
1539
+ return; /* We're done. */
1540
+ default:
1541
+ break;
1542
+ }
1543
+ }
1544
+ }
1545
+ }
1546
+
1547
+ /* Finish a FuncState and return the new prototype. */
1548
+ static GCproto *fs_finish(LexState *ls, BCLine line)
1549
+ {
1550
+ lua_State *L = ls->L;
1551
+ FuncState *fs = ls->fs;
1552
+ BCLine numline = line - fs->linedefined;
1553
+ size_t sizept, ofsk, ofsuv, ofsli, ofsdbg, ofsvar;
1554
+ GCproto *pt;
1555
+
1556
+ /* Apply final fixups. */
1557
+ fs_fixup_ret(fs);
1558
+
1559
+ /* Calculate total size of prototype including all colocated arrays. */
1560
+ sizept = sizeof(GCproto) + fs->pc*sizeof(BCIns) + fs->nkgc*sizeof(GCRef);
1561
+ sizept = (sizept + sizeof(TValue)-1) & ~(sizeof(TValue)-1);
1562
+ ofsk = sizept; sizept += fs->nkn*sizeof(TValue);
1563
+ ofsuv = sizept; sizept += ((fs->nuv+1)&~1)*2;
1564
+ ofsli = sizept; sizept += fs_prep_line(fs, numline);
1565
+ ofsdbg = sizept; sizept += fs_prep_var(ls, fs, &ofsvar);
1566
+
1567
+ /* Allocate prototype and initialize its fields. */
1568
+ pt = (GCproto *)lj_mem_newgco(L, (MSize)sizept);
1569
+ pt->gct = ~LJ_TPROTO;
1570
+ pt->sizept = (MSize)sizept;
1571
+ pt->trace = 0;
1572
+ pt->flags = (uint8_t)(fs->flags & ~(PROTO_HAS_RETURN|PROTO_FIXUP_RETURN));
1573
+ pt->numparams = fs->numparams;
1574
+ pt->framesize = fs->framesize;
1575
+ setgcref(pt->chunkname, obj2gco(ls->chunkname));
1576
+
1577
+ /* Close potentially uninitialized gap between bc and kgc. */
1578
+ *(uint32_t *)((char *)pt + ofsk - sizeof(GCRef)*(fs->nkgc+1)) = 0;
1579
+ fs_fixup_bc(fs, pt, (BCIns *)((char *)pt + sizeof(GCproto)), fs->pc);
1580
+ fs_fixup_k(fs, pt, (void *)((char *)pt + ofsk));
1581
+ fs_fixup_uv1(fs, pt, (uint16_t *)((char *)pt + ofsuv));
1582
+ fs_fixup_line(fs, pt, (void *)((char *)pt + ofsli), numline);
1583
+ fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar);
1584
+
1585
+ lj_vmevent_send(L, BC,
1586
+ setprotoV(L, L->top++, pt);
1587
+ );
1588
+
1589
+ L->top--; /* Pop table of constants. */
1590
+ ls->vtop = fs->vbase; /* Reset variable stack. */
1591
+ ls->fs = fs->prev;
1592
+ lua_assert(ls->fs != NULL || ls->tok == TK_eof);
1593
+ return pt;
1594
+ }
1595
+
1596
+ /* Initialize a new FuncState. */
1597
+ static void fs_init(LexState *ls, FuncState *fs)
1598
+ {
1599
+ lua_State *L = ls->L;
1600
+ fs->prev = ls->fs; ls->fs = fs; /* Append to list. */
1601
+ fs->ls = ls;
1602
+ fs->vbase = ls->vtop;
1603
+ fs->L = L;
1604
+ fs->pc = 0;
1605
+ fs->lasttarget = 0;
1606
+ fs->jpc = NO_JMP;
1607
+ fs->freereg = 0;
1608
+ fs->nkgc = 0;
1609
+ fs->nkn = 0;
1610
+ fs->nactvar = 0;
1611
+ fs->nuv = 0;
1612
+ fs->bl = NULL;
1613
+ fs->flags = 0;
1614
+ fs->framesize = 1; /* Minimum frame size. */
1615
+ fs->kt = lj_tab_new(L, 0, 0);
1616
+ /* Anchor table of constants in stack to avoid being collected. */
1617
+ settabV(L, L->top, fs->kt);
1618
+ incr_top(L);
1619
+ }
1620
+
1621
+ /* -- Expressions --------------------------------------------------------- */
1622
+
1623
+ /* Forward declaration. */
1624
+ static void expr(LexState *ls, ExpDesc *v);
1625
+
1626
+ /* Return string expression. */
1627
+ static void expr_str(LexState *ls, ExpDesc *e)
1628
+ {
1629
+ expr_init(e, VKSTR, 0);
1630
+ e->u.sval = lex_str(ls);
1631
+ }
1632
+
1633
+ /* Return index expression. */
1634
+ static void expr_index(FuncState *fs, ExpDesc *t, ExpDesc *e)
1635
+ {
1636
+ /* Already called: expr_toval(fs, e). */
1637
+ t->k = VINDEXED;
1638
+ if (expr_isnumk(e)) {
1639
+ #if LJ_DUALNUM
1640
+ if (tvisint(expr_numtv(e))) {
1641
+ int32_t k = intV(expr_numtv(e));
1642
+ if (checku8(k)) {
1643
+ t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */
1644
+ return;
1645
+ }
1646
+ }
1647
+ #else
1648
+ lua_Number n = expr_numberV(e);
1649
+ int32_t k = lj_num2int(n);
1650
+ if (checku8(k) && n == (lua_Number)k) {
1651
+ t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */
1652
+ return;
1653
+ }
1654
+ #endif
1655
+ } else if (expr_isstrk(e)) {
1656
+ BCReg idx = const_str(fs, e);
1657
+ if (idx <= BCMAX_C) {
1658
+ t->u.s.aux = ~idx; /* -256..-1: const string key */
1659
+ return;
1660
+ }
1661
+ }
1662
+ t->u.s.aux = expr_toanyreg(fs, e); /* 0..255: register */
1663
+ }
1664
+
1665
+ /* Parse index expression with named field. */
1666
+ static void expr_field(LexState *ls, ExpDesc *v)
1667
+ {
1668
+ FuncState *fs = ls->fs;
1669
+ ExpDesc key;
1670
+ expr_toanyreg(fs, v);
1671
+ lj_lex_next(ls); /* Skip dot or colon. */
1672
+ expr_str(ls, &key);
1673
+ expr_index(fs, v, &key);
1674
+ }
1675
+
1676
+ /* Parse index expression with brackets. */
1677
+ static void expr_bracket(LexState *ls, ExpDesc *v)
1678
+ {
1679
+ lj_lex_next(ls); /* Skip '['. */
1680
+ expr(ls, v);
1681
+ expr_toval(ls->fs, v);
1682
+ lex_check(ls, ']');
1683
+ }
1684
+
1685
+ /* Get value of constant expression. */
1686
+ static void expr_kvalue(TValue *v, ExpDesc *e)
1687
+ {
1688
+ if (e->k <= VKTRUE) {
1689
+ setpriV(v, ~(uint32_t)e->k);
1690
+ } else if (e->k == VKSTR) {
1691
+ setgcVraw(v, obj2gco(e->u.sval), LJ_TSTR);
1692
+ } else {
1693
+ lua_assert(tvisnumber(expr_numtv(e)));
1694
+ *v = *expr_numtv(e);
1695
+ }
1696
+ }
1697
+
1698
+ /* Parse table constructor expression. */
1699
+ static void expr_table(LexState *ls, ExpDesc *e)
1700
+ {
1701
+ FuncState *fs = ls->fs;
1702
+ BCLine line = ls->linenumber;
1703
+ GCtab *t = NULL;
1704
+ int vcall = 0, needarr = 0, fixt = 0;
1705
+ uint32_t narr = 1; /* First array index. */
1706
+ uint32_t nhash = 0; /* Number of hash entries. */
1707
+ BCReg freg = fs->freereg;
1708
+ BCPos pc = bcemit_AD(fs, BC_TNEW, freg, 0);
1709
+ expr_init(e, VNONRELOC, freg);
1710
+ bcreg_reserve(fs, 1);
1711
+ freg++;
1712
+ lex_check(ls, '{');
1713
+ while (ls->tok != '}') {
1714
+ ExpDesc key, val;
1715
+ vcall = 0;
1716
+ if (ls->tok == '[') {
1717
+ expr_bracket(ls, &key); /* Already calls expr_toval. */
1718
+ if (!expr_isk(&key)) expr_index(fs, e, &key);
1719
+ if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++;
1720
+ lex_check(ls, '=');
1721
+ } else if ((ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) &&
1722
+ lj_lex_lookahead(ls) == '=') {
1723
+ expr_str(ls, &key);
1724
+ lex_check(ls, '=');
1725
+ nhash++;
1726
+ } else {
1727
+ expr_init(&key, VKNUM, 0);
1728
+ setintV(&key.u.nval, (int)narr);
1729
+ narr++;
1730
+ needarr = vcall = 1;
1731
+ }
1732
+ expr(ls, &val);
1733
+ if (expr_isk(&key) && key.k != VKNIL &&
1734
+ (key.k == VKSTR || expr_isk_nojump(&val))) {
1735
+ TValue k, *v;
1736
+ if (!t) { /* Create template table on demand. */
1737
+ BCReg kidx;
1738
+ t = lj_tab_new(fs->L, needarr ? narr : 0, hsize2hbits(nhash));
1739
+ kidx = const_gc(fs, obj2gco(t), LJ_TTAB);
1740
+ fs->bcbase[pc].ins = BCINS_AD(BC_TDUP, freg-1, kidx);
1741
+ }
1742
+ vcall = 0;
1743
+ expr_kvalue(&k, &key);
1744
+ v = lj_tab_set(fs->L, t, &k);
1745
+ lj_gc_anybarriert(fs->L, t);
1746
+ if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */
1747
+ expr_kvalue(v, &val);
1748
+ } else { /* Otherwise create dummy string key (avoids lj_tab_newkey). */
1749
+ settabV(fs->L, v, t); /* Preserve key with table itself as value. */
1750
+ fixt = 1; /* Fix this later, after all resizes. */
1751
+ goto nonconst;
1752
+ }
1753
+ } else {
1754
+ nonconst:
1755
+ if (val.k != VCALL) { expr_toanyreg(fs, &val); vcall = 0; }
1756
+ if (expr_isk(&key)) expr_index(fs, e, &key);
1757
+ bcemit_store(fs, e, &val);
1758
+ }
1759
+ fs->freereg = freg;
1760
+ if (!lex_opt(ls, ',') && !lex_opt(ls, ';')) break;
1761
+ }
1762
+ lex_match(ls, '}', '{', line);
1763
+ if (vcall) {
1764
+ BCInsLine *ilp = &fs->bcbase[fs->pc-1];
1765
+ ExpDesc en;
1766
+ lua_assert(bc_a(ilp->ins) == freg &&
1767
+ bc_op(ilp->ins) == (narr > 256 ? BC_TSETV : BC_TSETB));
1768
+ expr_init(&en, VKNUM, 0);
1769
+ en.u.nval.u32.lo = narr-1;
1770
+ en.u.nval.u32.hi = 0x43300000; /* Biased integer to avoid denormals. */
1771
+ if (narr > 256) { fs->pc--; ilp--; }
1772
+ ilp->ins = BCINS_AD(BC_TSETM, freg, const_num(fs, &en));
1773
+ setbc_b(&ilp[-1].ins, 0);
1774
+ }
1775
+ if (pc == fs->pc-1) { /* Make expr relocable if possible. */
1776
+ e->u.s.info = pc;
1777
+ fs->freereg--;
1778
+ e->k = VRELOCABLE;
1779
+ } else {
1780
+ e->k = VNONRELOC; /* May have been changed by expr_index. */
1781
+ }
1782
+ if (!t) { /* Construct TNEW RD: hhhhhaaaaaaaaaaa. */
1783
+ BCIns *ip = &fs->bcbase[pc].ins;
1784
+ if (!needarr) narr = 0;
1785
+ else if (narr < 3) narr = 3;
1786
+ else if (narr > 0x7ff) narr = 0x7ff;
1787
+ setbc_d(ip, narr|(hsize2hbits(nhash)<<11));
1788
+ } else {
1789
+ if (needarr && t->asize < narr)
1790
+ lj_tab_reasize(fs->L, t, narr-1);
1791
+ if (fixt) { /* Fix value for dummy keys in template table. */
1792
+ Node *node = noderef(t->node);
1793
+ uint32_t i, hmask = t->hmask;
1794
+ for (i = 0; i <= hmask; i++) {
1795
+ Node *n = &node[i];
1796
+ if (tvistab(&n->val)) {
1797
+ lua_assert(tabV(&n->val) == t);
1798
+ setnilV(&n->val); /* Turn value into nil. */
1799
+ }
1800
+ }
1801
+ }
1802
+ lj_gc_check(fs->L);
1803
+ }
1804
+ }
1805
+
1806
+ /* Parse function parameters. */
1807
+ static BCReg parse_params(LexState *ls, int needself)
1808
+ {
1809
+ FuncState *fs = ls->fs;
1810
+ BCReg nparams = 0;
1811
+ lex_check(ls, '(');
1812
+ if (needself)
1813
+ var_new_lit(ls, nparams++, "self");
1814
+ if (ls->tok != ')') {
1815
+ do {
1816
+ if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) {
1817
+ var_new(ls, nparams++, lex_str(ls));
1818
+ } else if (ls->tok == TK_dots) {
1819
+ lj_lex_next(ls);
1820
+ fs->flags |= PROTO_VARARG;
1821
+ break;
1822
+ } else {
1823
+ err_syntax(ls, LJ_ERR_XPARAM);
1824
+ }
1825
+ } while (lex_opt(ls, ','));
1826
+ }
1827
+ var_add(ls, nparams);
1828
+ lua_assert(fs->nactvar == nparams);
1829
+ bcreg_reserve(fs, nparams);
1830
+ lex_check(ls, ')');
1831
+ return nparams;
1832
+ }
1833
+
1834
+ /* Forward declaration. */
1835
+ static void parse_chunk(LexState *ls);
1836
+
1837
+ /* Parse body of a function. */
1838
+ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line)
1839
+ {
1840
+ FuncState fs, *pfs = ls->fs;
1841
+ FuncScope bl;
1842
+ GCproto *pt;
1843
+ ptrdiff_t oldbase = pfs->bcbase - ls->bcstack;
1844
+ fs_init(ls, &fs);
1845
+ fscope_begin(&fs, &bl, 0);
1846
+ fs.linedefined = line;
1847
+ fs.numparams = (uint8_t)parse_params(ls, needself);
1848
+ fs.bcbase = pfs->bcbase + pfs->pc;
1849
+ fs.bclim = pfs->bclim - pfs->pc;
1850
+ bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */
1851
+ parse_chunk(ls);
1852
+ if (ls->tok != TK_end) lex_match(ls, TK_end, TK_function, line);
1853
+ pt = fs_finish(ls, (ls->lastline = ls->linenumber));
1854
+ pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */
1855
+ pfs->bclim = (BCPos)(ls->sizebcstack - oldbase);
1856
+ /* Store new prototype in the constant array of the parent. */
1857
+ expr_init(e, VRELOCABLE,
1858
+ bcemit_AD(pfs, BC_FNEW, 0, const_gc(pfs, obj2gco(pt), LJ_TPROTO)));
1859
+ #if LJ_HASFFI
1860
+ pfs->flags |= (fs.flags & PROTO_FFI);
1861
+ #endif
1862
+ if (!(pfs->flags & PROTO_CHILD)) {
1863
+ if (pfs->flags & PROTO_HAS_RETURN)
1864
+ pfs->flags |= PROTO_FIXUP_RETURN;
1865
+ pfs->flags |= PROTO_CHILD;
1866
+ }
1867
+ lj_lex_next(ls);
1868
+ }
1869
+
1870
+ /* Parse expression list. Last expression is left open. */
1871
+ static BCReg expr_list(LexState *ls, ExpDesc *v)
1872
+ {
1873
+ BCReg n = 1;
1874
+ expr(ls, v);
1875
+ while (lex_opt(ls, ',')) {
1876
+ expr_tonextreg(ls->fs, v);
1877
+ expr(ls, v);
1878
+ n++;
1879
+ }
1880
+ return n;
1881
+ }
1882
+
1883
+ /* Parse function argument list. */
1884
+ static void parse_args(LexState *ls, ExpDesc *e)
1885
+ {
1886
+ FuncState *fs = ls->fs;
1887
+ ExpDesc args;
1888
+ BCIns ins;
1889
+ BCReg base;
1890
+ BCLine line = ls->linenumber;
1891
+ if (ls->tok == '(') {
1892
+ #if !LJ_52
1893
+ if (line != ls->lastline)
1894
+ err_syntax(ls, LJ_ERR_XAMBIG);
1895
+ #endif
1896
+ lj_lex_next(ls);
1897
+ if (ls->tok == ')') { /* f(). */
1898
+ args.k = VVOID;
1899
+ } else {
1900
+ expr_list(ls, &args);
1901
+ if (args.k == VCALL) /* f(a, b, g()) or f(a, b, ...). */
1902
+ setbc_b(bcptr(fs, &args), 0); /* Pass on multiple results. */
1903
+ }
1904
+ lex_match(ls, ')', '(', line);
1905
+ } else if (ls->tok == '{') {
1906
+ expr_table(ls, &args);
1907
+ } else if (ls->tok == TK_string) {
1908
+ expr_init(&args, VKSTR, 0);
1909
+ args.u.sval = strV(&ls->tokval);
1910
+ lj_lex_next(ls);
1911
+ } else {
1912
+ err_syntax(ls, LJ_ERR_XFUNARG);
1913
+ return; /* Silence compiler. */
1914
+ }
1915
+ lua_assert(e->k == VNONRELOC);
1916
+ base = e->u.s.info; /* Base register for call. */
1917
+ if (args.k == VCALL) {
1918
+ ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1 - LJ_FR2);
1919
+ } else {
1920
+ if (args.k != VVOID)
1921
+ expr_tonextreg(fs, &args);
1922
+ ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base - LJ_FR2);
1923
+ }
1924
+ expr_init(e, VCALL, bcemit_INS(fs, ins));
1925
+ e->u.s.aux = base;
1926
+ fs->bcbase[fs->pc - 1].line = line;
1927
+ fs->freereg = base+1; /* Leave one result by default. */
1928
+ }
1929
+
1930
+ /* Parse primary expression. */
1931
+ static void expr_primary(LexState *ls, ExpDesc *v)
1932
+ {
1933
+ FuncState *fs = ls->fs;
1934
+ /* Parse prefix expression. */
1935
+ if (ls->tok == '(') {
1936
+ BCLine line = ls->linenumber;
1937
+ lj_lex_next(ls);
1938
+ expr(ls, v);
1939
+ lex_match(ls, ')', '(', line);
1940
+ expr_discharge(ls->fs, v);
1941
+ } else if (ls->tok == TK_name || (!LJ_52 && ls->tok == TK_goto)) {
1942
+ var_lookup(ls, v);
1943
+ } else {
1944
+ err_syntax(ls, LJ_ERR_XSYMBOL);
1945
+ }
1946
+ for (;;) { /* Parse multiple expression suffixes. */
1947
+ if (ls->tok == '.') {
1948
+ expr_field(ls, v);
1949
+ } else if (ls->tok == '[') {
1950
+ ExpDesc key;
1951
+ expr_toanyreg(fs, v);
1952
+ expr_bracket(ls, &key);
1953
+ expr_index(fs, v, &key);
1954
+ } else if (ls->tok == ':') {
1955
+ ExpDesc key;
1956
+ lj_lex_next(ls);
1957
+ expr_str(ls, &key);
1958
+ bcemit_method(fs, v, &key);
1959
+ parse_args(ls, v);
1960
+ } else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') {
1961
+ expr_tonextreg(fs, v);
1962
+ if (LJ_FR2) bcreg_reserve(fs, 1);
1963
+ parse_args(ls, v);
1964
+ } else {
1965
+ break;
1966
+ }
1967
+ }
1968
+ }
1969
+
1970
+ /* Parse simple expression. */
1971
+ static void expr_simple(LexState *ls, ExpDesc *v)
1972
+ {
1973
+ switch (ls->tok) {
1974
+ case TK_number:
1975
+ expr_init(v, (LJ_HASFFI && tviscdata(&ls->tokval)) ? VKCDATA : VKNUM, 0);
1976
+ copyTV(ls->L, &v->u.nval, &ls->tokval);
1977
+ break;
1978
+ case TK_string:
1979
+ expr_init(v, VKSTR, 0);
1980
+ v->u.sval = strV(&ls->tokval);
1981
+ break;
1982
+ case TK_nil:
1983
+ expr_init(v, VKNIL, 0);
1984
+ break;
1985
+ case TK_true:
1986
+ expr_init(v, VKTRUE, 0);
1987
+ break;
1988
+ case TK_false:
1989
+ expr_init(v, VKFALSE, 0);
1990
+ break;
1991
+ case TK_dots: { /* Vararg. */
1992
+ FuncState *fs = ls->fs;
1993
+ BCReg base;
1994
+ checkcond(ls, fs->flags & PROTO_VARARG, LJ_ERR_XDOTS);
1995
+ bcreg_reserve(fs, 1);
1996
+ base = fs->freereg-1;
1997
+ expr_init(v, VCALL, bcemit_ABC(fs, BC_VARG, base, 2, fs->numparams));
1998
+ v->u.s.aux = base;
1999
+ break;
2000
+ }
2001
+ case '{': /* Table constructor. */
2002
+ expr_table(ls, v);
2003
+ return;
2004
+ case TK_function:
2005
+ lj_lex_next(ls);
2006
+ parse_body(ls, v, 0, ls->linenumber);
2007
+ return;
2008
+ default:
2009
+ expr_primary(ls, v);
2010
+ return;
2011
+ }
2012
+ lj_lex_next(ls);
2013
+ }
2014
+
2015
+ /* Manage syntactic levels to avoid blowing up the stack. */
2016
+ static void synlevel_begin(LexState *ls)
2017
+ {
2018
+ if (++ls->level >= LJ_MAX_XLEVEL)
2019
+ lj_lex_error(ls, 0, LJ_ERR_XLEVELS);
2020
+ }
2021
+
2022
+ #define synlevel_end(ls) ((ls)->level--)
2023
+
2024
+ /* Convert token to binary operator. */
2025
+ static BinOpr token2binop(LexToken tok)
2026
+ {
2027
+ switch (tok) {
2028
+ case '+': return OPR_ADD;
2029
+ case '-': return OPR_SUB;
2030
+ case '*': return OPR_MUL;
2031
+ case '/': return OPR_DIV;
2032
+ case '%': return OPR_MOD;
2033
+ case '^': return OPR_POW;
2034
+ case TK_concat: return OPR_CONCAT;
2035
+ case TK_ne: return OPR_NE;
2036
+ case TK_eq: return OPR_EQ;
2037
+ case '<': return OPR_LT;
2038
+ case TK_le: return OPR_LE;
2039
+ case '>': return OPR_GT;
2040
+ case TK_ge: return OPR_GE;
2041
+ case TK_and: return OPR_AND;
2042
+ case TK_or: return OPR_OR;
2043
+ default: return OPR_NOBINOPR;
2044
+ }
2045
+ }
2046
+
2047
+ /* Priorities for each binary operator. ORDER OPR. */
2048
+ static const struct {
2049
+ uint8_t left; /* Left priority. */
2050
+ uint8_t right; /* Right priority. */
2051
+ } priority[] = {
2052
+ {6,6}, {6,6}, {7,7}, {7,7}, {7,7}, /* ADD SUB MUL DIV MOD */
2053
+ {10,9}, {5,4}, /* POW CONCAT (right associative) */
2054
+ {3,3}, {3,3}, /* EQ NE */
2055
+ {3,3}, {3,3}, {3,3}, {3,3}, /* LT GE GT LE */
2056
+ {2,2}, {1,1} /* AND OR */
2057
+ };
2058
+
2059
+ #define UNARY_PRIORITY 8 /* Priority for unary operators. */
2060
+
2061
+ /* Forward declaration. */
2062
+ static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit);
2063
+
2064
+ /* Parse unary expression. */
2065
+ static void expr_unop(LexState *ls, ExpDesc *v)
2066
+ {
2067
+ BCOp op;
2068
+ if (ls->tok == TK_not) {
2069
+ op = BC_NOT;
2070
+ } else if (ls->tok == '-') {
2071
+ op = BC_UNM;
2072
+ } else if (ls->tok == '#') {
2073
+ op = BC_LEN;
2074
+ } else {
2075
+ expr_simple(ls, v);
2076
+ return;
2077
+ }
2078
+ lj_lex_next(ls);
2079
+ expr_binop(ls, v, UNARY_PRIORITY);
2080
+ bcemit_unop(ls->fs, op, v);
2081
+ }
2082
+
2083
+ /* Parse binary expressions with priority higher than the limit. */
2084
+ static BinOpr expr_binop(LexState *ls, ExpDesc *v, uint32_t limit)
2085
+ {
2086
+ BinOpr op;
2087
+ synlevel_begin(ls);
2088
+ expr_unop(ls, v);
2089
+ op = token2binop(ls->tok);
2090
+ while (op != OPR_NOBINOPR && priority[op].left > limit) {
2091
+ ExpDesc v2;
2092
+ BinOpr nextop;
2093
+ lj_lex_next(ls);
2094
+ bcemit_binop_left(ls->fs, op, v);
2095
+ /* Parse binary expression with higher priority. */
2096
+ nextop = expr_binop(ls, &v2, priority[op].right);
2097
+ bcemit_binop(ls->fs, op, v, &v2);
2098
+ op = nextop;
2099
+ }
2100
+ synlevel_end(ls);
2101
+ return op; /* Return unconsumed binary operator (if any). */
2102
+ }
2103
+
2104
+ /* Parse expression. */
2105
+ static void expr(LexState *ls, ExpDesc *v)
2106
+ {
2107
+ expr_binop(ls, v, 0); /* Priority 0: parse whole expression. */
2108
+ }
2109
+
2110
+ /* Assign expression to the next register. */
2111
+ static void expr_next(LexState *ls)
2112
+ {
2113
+ ExpDesc e;
2114
+ expr(ls, &e);
2115
+ expr_tonextreg(ls->fs, &e);
2116
+ }
2117
+
2118
+ /* Parse conditional expression. */
2119
+ static BCPos expr_cond(LexState *ls)
2120
+ {
2121
+ ExpDesc v;
2122
+ expr(ls, &v);
2123
+ if (v.k == VKNIL) v.k = VKFALSE;
2124
+ bcemit_branch_t(ls->fs, &v);
2125
+ return v.f;
2126
+ }
2127
+
2128
+ /* -- Assignments --------------------------------------------------------- */
2129
+
2130
+ /* List of LHS variables. */
2131
+ typedef struct LHSVarList {
2132
+ ExpDesc v; /* LHS variable. */
2133
+ struct LHSVarList *prev; /* Link to previous LHS variable. */
2134
+ } LHSVarList;
2135
+
2136
+ /* Eliminate write-after-read hazards for local variable assignment. */
2137
+ static void assign_hazard(LexState *ls, LHSVarList *lh, const ExpDesc *v)
2138
+ {
2139
+ FuncState *fs = ls->fs;
2140
+ BCReg reg = v->u.s.info; /* Check against this variable. */
2141
+ BCReg tmp = fs->freereg; /* Rename to this temp. register (if needed). */
2142
+ int hazard = 0;
2143
+ for (; lh; lh = lh->prev) {
2144
+ if (lh->v.k == VINDEXED) {
2145
+ if (lh->v.u.s.info == reg) { /* t[i], t = 1, 2 */
2146
+ hazard = 1;
2147
+ lh->v.u.s.info = tmp;
2148
+ }
2149
+ if (lh->v.u.s.aux == reg) { /* t[i], i = 1, 2 */
2150
+ hazard = 1;
2151
+ lh->v.u.s.aux = tmp;
2152
+ }
2153
+ }
2154
+ }
2155
+ if (hazard) {
2156
+ bcemit_AD(fs, BC_MOV, tmp, reg); /* Rename conflicting variable. */
2157
+ bcreg_reserve(fs, 1);
2158
+ }
2159
+ }
2160
+
2161
+ /* Adjust LHS/RHS of an assignment. */
2162
+ static void assign_adjust(LexState *ls, BCReg nvars, BCReg nexps, ExpDesc *e)
2163
+ {
2164
+ FuncState *fs = ls->fs;
2165
+ int32_t extra = (int32_t)nvars - (int32_t)nexps;
2166
+ if (e->k == VCALL) {
2167
+ extra++; /* Compensate for the VCALL itself. */
2168
+ if (extra < 0) extra = 0;
2169
+ setbc_b(bcptr(fs, e), extra+1); /* Fixup call results. */
2170
+ if (extra > 1) bcreg_reserve(fs, (BCReg)extra-1);
2171
+ } else {
2172
+ if (e->k != VVOID)
2173
+ expr_tonextreg(fs, e); /* Close last expression. */
2174
+ if (extra > 0) { /* Leftover LHS are set to nil. */
2175
+ BCReg reg = fs->freereg;
2176
+ bcreg_reserve(fs, (BCReg)extra);
2177
+ bcemit_nil(fs, reg, (BCReg)extra);
2178
+ }
2179
+ }
2180
+ }
2181
+
2182
+ /* Recursively parse assignment statement. */
2183
+ static void parse_assignment(LexState *ls, LHSVarList *lh, BCReg nvars)
2184
+ {
2185
+ ExpDesc e;
2186
+ checkcond(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, LJ_ERR_XSYNTAX);
2187
+ if (lex_opt(ls, ',')) { /* Collect LHS list and recurse upwards. */
2188
+ LHSVarList vl;
2189
+ vl.prev = lh;
2190
+ expr_primary(ls, &vl.v);
2191
+ if (vl.v.k == VLOCAL)
2192
+ assign_hazard(ls, lh, &vl.v);
2193
+ checklimit(ls->fs, ls->level + nvars, LJ_MAX_XLEVEL, "variable names");
2194
+ parse_assignment(ls, &vl, nvars+1);
2195
+ } else { /* Parse RHS. */
2196
+ BCReg nexps;
2197
+ lex_check(ls, '=');
2198
+ nexps = expr_list(ls, &e);
2199
+ if (nexps == nvars) {
2200
+ if (e.k == VCALL) {
2201
+ if (bc_op(*bcptr(ls->fs, &e)) == BC_VARG) { /* Vararg assignment. */
2202
+ ls->fs->freereg--;
2203
+ e.k = VRELOCABLE;
2204
+ } else { /* Multiple call results. */
2205
+ e.u.s.info = e.u.s.aux; /* Base of call is not relocatable. */
2206
+ e.k = VNONRELOC;
2207
+ }
2208
+ }
2209
+ bcemit_store(ls->fs, &lh->v, &e);
2210
+ return;
2211
+ }
2212
+ assign_adjust(ls, nvars, nexps, &e);
2213
+ if (nexps > nvars)
2214
+ ls->fs->freereg -= nexps - nvars; /* Drop leftover regs. */
2215
+ }
2216
+ /* Assign RHS to LHS and recurse downwards. */
2217
+ expr_init(&e, VNONRELOC, ls->fs->freereg-1);
2218
+ bcemit_store(ls->fs, &lh->v, &e);
2219
+ }
2220
+
2221
+ /* Parse call statement or assignment. */
2222
+ static void parse_call_assign(LexState *ls)
2223
+ {
2224
+ FuncState *fs = ls->fs;
2225
+ LHSVarList vl;
2226
+ expr_primary(ls, &vl.v);
2227
+ if (vl.v.k == VCALL) { /* Function call statement. */
2228
+ setbc_b(bcptr(fs, &vl.v), 1); /* No results. */
2229
+ } else { /* Start of an assignment. */
2230
+ vl.prev = NULL;
2231
+ parse_assignment(ls, &vl, 1);
2232
+ }
2233
+ }
2234
+
2235
+ /* Parse 'local' statement. */
2236
+ static void parse_local(LexState *ls)
2237
+ {
2238
+ if (lex_opt(ls, TK_function)) { /* Local function declaration. */
2239
+ ExpDesc v, b;
2240
+ FuncState *fs = ls->fs;
2241
+ var_new(ls, 0, lex_str(ls));
2242
+ expr_init(&v, VLOCAL, fs->freereg);
2243
+ v.u.s.aux = fs->varmap[fs->freereg];
2244
+ bcreg_reserve(fs, 1);
2245
+ var_add(ls, 1);
2246
+ parse_body(ls, &b, 0, ls->linenumber);
2247
+ /* bcemit_store(fs, &v, &b) without setting VSTACK_VAR_RW. */
2248
+ expr_free(fs, &b);
2249
+ expr_toreg(fs, &b, v.u.s.info);
2250
+ /* The upvalue is in scope, but the local is only valid after the store. */
2251
+ var_get(ls, fs, fs->nactvar - 1).startpc = fs->pc;
2252
+ } else { /* Local variable declaration. */
2253
+ ExpDesc e;
2254
+ BCReg nexps, nvars = 0;
2255
+ do { /* Collect LHS. */
2256
+ var_new(ls, nvars++, lex_str(ls));
2257
+ } while (lex_opt(ls, ','));
2258
+ if (lex_opt(ls, '=')) { /* Optional RHS. */
2259
+ nexps = expr_list(ls, &e);
2260
+ } else { /* Or implicitly set to nil. */
2261
+ e.k = VVOID;
2262
+ nexps = 0;
2263
+ }
2264
+ assign_adjust(ls, nvars, nexps, &e);
2265
+ var_add(ls, nvars);
2266
+ }
2267
+ }
2268
+
2269
+ /* Parse 'function' statement. */
2270
+ static void parse_func(LexState *ls, BCLine line)
2271
+ {
2272
+ FuncState *fs;
2273
+ ExpDesc v, b;
2274
+ int needself = 0;
2275
+ lj_lex_next(ls); /* Skip 'function'. */
2276
+ /* Parse function name. */
2277
+ var_lookup(ls, &v);
2278
+ while (ls->tok == '.') /* Multiple dot-separated fields. */
2279
+ expr_field(ls, &v);
2280
+ if (ls->tok == ':') { /* Optional colon to signify method call. */
2281
+ needself = 1;
2282
+ expr_field(ls, &v);
2283
+ }
2284
+ parse_body(ls, &b, needself, line);
2285
+ fs = ls->fs;
2286
+ bcemit_store(fs, &v, &b);
2287
+ fs->bcbase[fs->pc - 1].line = line; /* Set line for the store. */
2288
+ }
2289
+
2290
+ /* -- Control transfer statements ----------------------------------------- */
2291
+
2292
+ /* Check for end of block. */
2293
+ static int parse_isend(LexToken tok)
2294
+ {
2295
+ switch (tok) {
2296
+ case TK_else: case TK_elseif: case TK_end: case TK_until: case TK_eof:
2297
+ return 1;
2298
+ default:
2299
+ return 0;
2300
+ }
2301
+ }
2302
+
2303
+ /* Parse 'return' statement. */
2304
+ static void parse_return(LexState *ls)
2305
+ {
2306
+ BCIns ins;
2307
+ FuncState *fs = ls->fs;
2308
+ lj_lex_next(ls); /* Skip 'return'. */
2309
+ fs->flags |= PROTO_HAS_RETURN;
2310
+ if (parse_isend(ls->tok) || ls->tok == ';') { /* Bare return. */
2311
+ ins = BCINS_AD(BC_RET0, 0, 1);
2312
+ } else { /* Return with one or more values. */
2313
+ ExpDesc e; /* Receives the _last_ expression in the list. */
2314
+ BCReg nret = expr_list(ls, &e);
2315
+ if (nret == 1) { /* Return one result. */
2316
+ if (e.k == VCALL) { /* Check for tail call. */
2317
+ BCIns *ip = bcptr(fs, &e);
2318
+ /* It doesn't pay off to add BC_VARGT just for 'return ...'. */
2319
+ if (bc_op(*ip) == BC_VARG) goto notailcall;
2320
+ fs->pc--;
2321
+ ins = BCINS_AD(bc_op(*ip)-BC_CALL+BC_CALLT, bc_a(*ip), bc_c(*ip));
2322
+ } else { /* Can return the result from any register. */
2323
+ ins = BCINS_AD(BC_RET1, expr_toanyreg(fs, &e), 2);
2324
+ }
2325
+ } else {
2326
+ if (e.k == VCALL) { /* Append all results from a call. */
2327
+ notailcall:
2328
+ setbc_b(bcptr(fs, &e), 0);
2329
+ ins = BCINS_AD(BC_RETM, fs->nactvar, e.u.s.aux - fs->nactvar);
2330
+ } else {
2331
+ expr_tonextreg(fs, &e); /* Force contiguous registers. */
2332
+ ins = BCINS_AD(BC_RET, fs->nactvar, nret+1);
2333
+ }
2334
+ }
2335
+ }
2336
+ if (fs->flags & PROTO_CHILD)
2337
+ bcemit_AJ(fs, BC_UCLO, 0, 0); /* May need to close upvalues first. */
2338
+ bcemit_INS(fs, ins);
2339
+ }
2340
+
2341
+ /* Parse 'break' statement. */
2342
+ static void parse_break(LexState *ls)
2343
+ {
2344
+ ls->fs->bl->flags |= FSCOPE_BREAK;
2345
+ gola_new(ls, NAME_BREAK, VSTACK_GOTO, bcemit_jmp(ls->fs));
2346
+ }
2347
+
2348
+ /* Parse 'goto' statement. */
2349
+ static void parse_goto(LexState *ls)
2350
+ {
2351
+ FuncState *fs = ls->fs;
2352
+ GCstr *name = lex_str(ls);
2353
+ VarInfo *vl = gola_findlabel(ls, name);
2354
+ if (vl) /* Treat backwards goto within same scope like a loop. */
2355
+ bcemit_AJ(fs, BC_LOOP, vl->slot, -1); /* No BC range check. */
2356
+ fs->bl->flags |= FSCOPE_GOLA;
2357
+ gola_new(ls, name, VSTACK_GOTO, bcemit_jmp(fs));
2358
+ }
2359
+
2360
+ /* Parse label. */
2361
+ static void parse_label(LexState *ls)
2362
+ {
2363
+ FuncState *fs = ls->fs;
2364
+ GCstr *name;
2365
+ MSize idx;
2366
+ fs->lasttarget = fs->pc;
2367
+ fs->bl->flags |= FSCOPE_GOLA;
2368
+ lj_lex_next(ls); /* Skip '::'. */
2369
+ name = lex_str(ls);
2370
+ if (gola_findlabel(ls, name))
2371
+ lj_lex_error(ls, 0, LJ_ERR_XLDUP, strdata(name));
2372
+ idx = gola_new(ls, name, VSTACK_LABEL, fs->pc);
2373
+ lex_check(ls, TK_label);
2374
+ /* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */
2375
+ for (;;) {
2376
+ if (ls->tok == TK_label) {
2377
+ synlevel_begin(ls);
2378
+ parse_label(ls);
2379
+ synlevel_end(ls);
2380
+ } else if (LJ_52 && ls->tok == ';') {
2381
+ lj_lex_next(ls);
2382
+ } else {
2383
+ break;
2384
+ }
2385
+ }
2386
+ /* Trailing label is considered to be outside of scope. */
2387
+ if (parse_isend(ls->tok) && ls->tok != TK_until)
2388
+ ls->vstack[idx].slot = fs->bl->nactvar;
2389
+ gola_resolve(ls, fs->bl, idx);
2390
+ }
2391
+
2392
+ /* -- Blocks, loops and conditional statements ---------------------------- */
2393
+
2394
+ /* Parse a block. */
2395
+ static void parse_block(LexState *ls)
2396
+ {
2397
+ FuncState *fs = ls->fs;
2398
+ FuncScope bl;
2399
+ fscope_begin(fs, &bl, 0);
2400
+ parse_chunk(ls);
2401
+ fscope_end(fs);
2402
+ }
2403
+
2404
+ /* Parse 'while' statement. */
2405
+ static void parse_while(LexState *ls, BCLine line)
2406
+ {
2407
+ FuncState *fs = ls->fs;
2408
+ BCPos start, loop, condexit;
2409
+ FuncScope bl;
2410
+ lj_lex_next(ls); /* Skip 'while'. */
2411
+ start = fs->lasttarget = fs->pc;
2412
+ condexit = expr_cond(ls);
2413
+ fscope_begin(fs, &bl, FSCOPE_LOOP);
2414
+ lex_check(ls, TK_do);
2415
+ loop = bcemit_AD(fs, BC_LOOP, fs->nactvar, 0);
2416
+ parse_block(ls);
2417
+ jmp_patch(fs, bcemit_jmp(fs), start);
2418
+ lex_match(ls, TK_end, TK_while, line);
2419
+ fscope_end(fs);
2420
+ jmp_tohere(fs, condexit);
2421
+ jmp_patchins(fs, loop, fs->pc);
2422
+ }
2423
+
2424
+ /* Parse 'repeat' statement. */
2425
+ static void parse_repeat(LexState *ls, BCLine line)
2426
+ {
2427
+ FuncState *fs = ls->fs;
2428
+ BCPos loop = fs->lasttarget = fs->pc;
2429
+ BCPos condexit;
2430
+ FuncScope bl1, bl2;
2431
+ fscope_begin(fs, &bl1, FSCOPE_LOOP); /* Breakable loop scope. */
2432
+ fscope_begin(fs, &bl2, 0); /* Inner scope. */
2433
+ lj_lex_next(ls); /* Skip 'repeat'. */
2434
+ bcemit_AD(fs, BC_LOOP, fs->nactvar, 0);
2435
+ parse_chunk(ls);
2436
+ lex_match(ls, TK_until, TK_repeat, line);
2437
+ condexit = expr_cond(ls); /* Parse condition (still inside inner scope). */
2438
+ if (!(bl2.flags & FSCOPE_UPVAL)) { /* No upvalues? Just end inner scope. */
2439
+ fscope_end(fs);
2440
+ } else { /* Otherwise generate: cond: UCLO+JMP out, !cond: UCLO+JMP loop. */
2441
+ parse_break(ls); /* Break from loop and close upvalues. */
2442
+ jmp_tohere(fs, condexit);
2443
+ fscope_end(fs); /* End inner scope and close upvalues. */
2444
+ condexit = bcemit_jmp(fs);
2445
+ }
2446
+ jmp_patch(fs, condexit, loop); /* Jump backwards if !cond. */
2447
+ jmp_patchins(fs, loop, fs->pc);
2448
+ fscope_end(fs); /* End loop scope. */
2449
+ }
2450
+
2451
+ /* Parse numeric 'for'. */
2452
+ static void parse_for_num(LexState *ls, GCstr *varname, BCLine line)
2453
+ {
2454
+ FuncState *fs = ls->fs;
2455
+ BCReg base = fs->freereg;
2456
+ FuncScope bl;
2457
+ BCPos loop, loopend;
2458
+ /* Hidden control variables. */
2459
+ var_new_fixed(ls, FORL_IDX, VARNAME_FOR_IDX);
2460
+ var_new_fixed(ls, FORL_STOP, VARNAME_FOR_STOP);
2461
+ var_new_fixed(ls, FORL_STEP, VARNAME_FOR_STEP);
2462
+ /* Visible copy of index variable. */
2463
+ var_new(ls, FORL_EXT, varname);
2464
+ lex_check(ls, '=');
2465
+ expr_next(ls);
2466
+ lex_check(ls, ',');
2467
+ expr_next(ls);
2468
+ if (lex_opt(ls, ',')) {
2469
+ expr_next(ls);
2470
+ } else {
2471
+ bcemit_AD(fs, BC_KSHORT, fs->freereg, 1); /* Default step is 1. */
2472
+ bcreg_reserve(fs, 1);
2473
+ }
2474
+ var_add(ls, 3); /* Hidden control variables. */
2475
+ lex_check(ls, TK_do);
2476
+ loop = bcemit_AJ(fs, BC_FORI, base, NO_JMP);
2477
+ fscope_begin(fs, &bl, 0); /* Scope for visible variables. */
2478
+ var_add(ls, 1);
2479
+ bcreg_reserve(fs, 1);
2480
+ parse_block(ls);
2481
+ fscope_end(fs);
2482
+ /* Perform loop inversion. Loop control instructions are at the end. */
2483
+ loopend = bcemit_AJ(fs, BC_FORL, base, NO_JMP);
2484
+ fs->bcbase[loopend].line = line; /* Fix line for control ins. */
2485
+ jmp_patchins(fs, loopend, loop+1);
2486
+ jmp_patchins(fs, loop, fs->pc);
2487
+ }
2488
+
2489
+ /* Try to predict whether the iterator is next() and specialize the bytecode.
2490
+ ** Detecting next() and pairs() by name is simplistic, but quite effective.
2491
+ ** The interpreter backs off if the check for the closure fails at runtime.
2492
+ */
2493
+ static int predict_next(LexState *ls, FuncState *fs, BCPos pc)
2494
+ {
2495
+ BCIns ins = fs->bcbase[pc].ins;
2496
+ GCstr *name;
2497
+ cTValue *o;
2498
+ switch (bc_op(ins)) {
2499
+ case BC_MOV:
2500
+ name = gco2str(gcref(var_get(ls, fs, bc_d(ins)).name));
2501
+ break;
2502
+ case BC_UGET:
2503
+ name = gco2str(gcref(ls->vstack[fs->uvmap[bc_d(ins)]].name));
2504
+ break;
2505
+ case BC_GGET:
2506
+ /* There's no inverse index (yet), so lookup the strings. */
2507
+ o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "pairs"));
2508
+ if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins))
2509
+ return 1;
2510
+ o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "next"));
2511
+ if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins))
2512
+ return 1;
2513
+ return 0;
2514
+ default:
2515
+ return 0;
2516
+ }
2517
+ return (name->len == 5 && !strcmp(strdata(name), "pairs")) ||
2518
+ (name->len == 4 && !strcmp(strdata(name), "next"));
2519
+ }
2520
+
2521
+ /* Parse 'for' iterator. */
2522
+ static void parse_for_iter(LexState *ls, GCstr *indexname)
2523
+ {
2524
+ FuncState *fs = ls->fs;
2525
+ ExpDesc e;
2526
+ BCReg nvars = 0;
2527
+ BCLine line;
2528
+ BCReg base = fs->freereg + 3;
2529
+ BCPos loop, loopend, exprpc = fs->pc;
2530
+ FuncScope bl;
2531
+ int isnext;
2532
+ /* Hidden control variables. */
2533
+ var_new_fixed(ls, nvars++, VARNAME_FOR_GEN);
2534
+ var_new_fixed(ls, nvars++, VARNAME_FOR_STATE);
2535
+ var_new_fixed(ls, nvars++, VARNAME_FOR_CTL);
2536
+ /* Visible variables returned from iterator. */
2537
+ var_new(ls, nvars++, indexname);
2538
+ while (lex_opt(ls, ','))
2539
+ var_new(ls, nvars++, lex_str(ls));
2540
+ lex_check(ls, TK_in);
2541
+ line = ls->linenumber;
2542
+ assign_adjust(ls, 3, expr_list(ls, &e), &e);
2543
+ /* The iterator needs another 3 [4] slots (func [pc] | state ctl). */
2544
+ bcreg_bump(fs, 3+LJ_FR2);
2545
+ isnext = (nvars <= 5 && predict_next(ls, fs, exprpc));
2546
+ var_add(ls, 3); /* Hidden control variables. */
2547
+ lex_check(ls, TK_do);
2548
+ loop = bcemit_AJ(fs, isnext ? BC_ISNEXT : BC_JMP, base, NO_JMP);
2549
+ fscope_begin(fs, &bl, 0); /* Scope for visible variables. */
2550
+ var_add(ls, nvars-3);
2551
+ bcreg_reserve(fs, nvars-3);
2552
+ parse_block(ls);
2553
+ fscope_end(fs);
2554
+ /* Perform loop inversion. Loop control instructions are at the end. */
2555
+ jmp_patchins(fs, loop, fs->pc);
2556
+ bcemit_ABC(fs, isnext ? BC_ITERN : BC_ITERC, base, nvars-3+1, 2+1);
2557
+ loopend = bcemit_AJ(fs, BC_ITERL, base, NO_JMP);
2558
+ fs->bcbase[loopend-1].line = line; /* Fix line for control ins. */
2559
+ fs->bcbase[loopend].line = line;
2560
+ jmp_patchins(fs, loopend, loop+1);
2561
+ }
2562
+
2563
+ /* Parse 'for' statement. */
2564
+ static void parse_for(LexState *ls, BCLine line)
2565
+ {
2566
+ FuncState *fs = ls->fs;
2567
+ GCstr *varname;
2568
+ FuncScope bl;
2569
+ fscope_begin(fs, &bl, FSCOPE_LOOP);
2570
+ lj_lex_next(ls); /* Skip 'for'. */
2571
+ varname = lex_str(ls); /* Get first variable name. */
2572
+ if (ls->tok == '=')
2573
+ parse_for_num(ls, varname, line);
2574
+ else if (ls->tok == ',' || ls->tok == TK_in)
2575
+ parse_for_iter(ls, varname);
2576
+ else
2577
+ err_syntax(ls, LJ_ERR_XFOR);
2578
+ lex_match(ls, TK_end, TK_for, line);
2579
+ fscope_end(fs); /* Resolve break list. */
2580
+ }
2581
+
2582
+ /* Parse condition and 'then' block. */
2583
+ static BCPos parse_then(LexState *ls)
2584
+ {
2585
+ BCPos condexit;
2586
+ lj_lex_next(ls); /* Skip 'if' or 'elseif'. */
2587
+ condexit = expr_cond(ls);
2588
+ lex_check(ls, TK_then);
2589
+ parse_block(ls);
2590
+ return condexit;
2591
+ }
2592
+
2593
+ /* Parse 'if' statement. */
2594
+ static void parse_if(LexState *ls, BCLine line)
2595
+ {
2596
+ FuncState *fs = ls->fs;
2597
+ BCPos flist;
2598
+ BCPos escapelist = NO_JMP;
2599
+ flist = parse_then(ls);
2600
+ while (ls->tok == TK_elseif) { /* Parse multiple 'elseif' blocks. */
2601
+ jmp_append(fs, &escapelist, bcemit_jmp(fs));
2602
+ jmp_tohere(fs, flist);
2603
+ flist = parse_then(ls);
2604
+ }
2605
+ if (ls->tok == TK_else) { /* Parse optional 'else' block. */
2606
+ jmp_append(fs, &escapelist, bcemit_jmp(fs));
2607
+ jmp_tohere(fs, flist);
2608
+ lj_lex_next(ls); /* Skip 'else'. */
2609
+ parse_block(ls);
2610
+ } else {
2611
+ jmp_append(fs, &escapelist, flist);
2612
+ }
2613
+ jmp_tohere(fs, escapelist);
2614
+ lex_match(ls, TK_end, TK_if, line);
2615
+ }
2616
+
2617
+ /* -- Parse statements ---------------------------------------------------- */
2618
+
2619
+ /* Parse a statement. Returns 1 if it must be the last one in a chunk. */
2620
+ static int parse_stmt(LexState *ls)
2621
+ {
2622
+ BCLine line = ls->linenumber;
2623
+ switch (ls->tok) {
2624
+ case TK_if:
2625
+ parse_if(ls, line);
2626
+ break;
2627
+ case TK_while:
2628
+ parse_while(ls, line);
2629
+ break;
2630
+ case TK_do:
2631
+ lj_lex_next(ls);
2632
+ parse_block(ls);
2633
+ lex_match(ls, TK_end, TK_do, line);
2634
+ break;
2635
+ case TK_for:
2636
+ parse_for(ls, line);
2637
+ break;
2638
+ case TK_repeat:
2639
+ parse_repeat(ls, line);
2640
+ break;
2641
+ case TK_function:
2642
+ parse_func(ls, line);
2643
+ break;
2644
+ case TK_local:
2645
+ lj_lex_next(ls);
2646
+ parse_local(ls);
2647
+ break;
2648
+ case TK_return:
2649
+ parse_return(ls);
2650
+ return 1; /* Must be last. */
2651
+ case TK_break:
2652
+ lj_lex_next(ls);
2653
+ parse_break(ls);
2654
+ return !LJ_52; /* Must be last in Lua 5.1. */
2655
+ #if LJ_52
2656
+ case ';':
2657
+ lj_lex_next(ls);
2658
+ break;
2659
+ #endif
2660
+ case TK_label:
2661
+ parse_label(ls);
2662
+ break;
2663
+ case TK_goto:
2664
+ if (LJ_52 || lj_lex_lookahead(ls) == TK_name) {
2665
+ lj_lex_next(ls);
2666
+ parse_goto(ls);
2667
+ break;
2668
+ } /* else: fallthrough */
2669
+ default:
2670
+ parse_call_assign(ls);
2671
+ break;
2672
+ }
2673
+ return 0;
2674
+ }
2675
+
2676
+ /* A chunk is a list of statements optionally separated by semicolons. */
2677
+ static void parse_chunk(LexState *ls)
2678
+ {
2679
+ int islast = 0;
2680
+ synlevel_begin(ls);
2681
+ while (!islast && !parse_isend(ls->tok)) {
2682
+ islast = parse_stmt(ls);
2683
+ lex_opt(ls, ';');
2684
+ lua_assert(ls->fs->framesize >= ls->fs->freereg &&
2685
+ ls->fs->freereg >= ls->fs->nactvar);
2686
+ ls->fs->freereg = ls->fs->nactvar; /* Free registers after each stmt. */
2687
+ }
2688
+ synlevel_end(ls);
2689
+ }
2690
+
2691
+ /* Entry point of bytecode parser. */
2692
+ GCproto *lj_parse(LexState *ls)
2693
+ {
2694
+ FuncState fs;
2695
+ FuncScope bl;
2696
+ GCproto *pt;
2697
+ lua_State *L = ls->L;
2698
+ #ifdef LUAJIT_DISABLE_DEBUGINFO
2699
+ ls->chunkname = lj_str_newlit(L, "=");
2700
+ #else
2701
+ ls->chunkname = lj_str_newz(L, ls->chunkarg);
2702
+ #endif
2703
+ setstrV(L, L->top, ls->chunkname); /* Anchor chunkname string. */
2704
+ incr_top(L);
2705
+ ls->level = 0;
2706
+ fs_init(ls, &fs);
2707
+ fs.linedefined = 0;
2708
+ fs.numparams = 0;
2709
+ fs.bcbase = NULL;
2710
+ fs.bclim = 0;
2711
+ fs.flags |= PROTO_VARARG; /* Main chunk is always a vararg func. */
2712
+ fscope_begin(&fs, &bl, 0);
2713
+ bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */
2714
+ lj_lex_next(ls); /* Read-ahead first token. */
2715
+ parse_chunk(ls);
2716
+ if (ls->tok != TK_eof)
2717
+ err_token(ls, TK_eof);
2718
+ pt = fs_finish(ls, ls->linenumber);
2719
+ L->top--; /* Drop chunkname. */
2720
+ lua_assert(fs.prev == NULL);
2721
+ lua_assert(ls->fs == NULL);
2722
+ lua_assert(pt->sizeuv == 0);
2723
+ return pt;
2724
+ }
2725
+