webruby 0.1.2 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (518) hide show
  1. checksums.yaml +4 -4
  2. data/driver/driver.c +12 -0
  3. data/lib/webruby/config.rb +3 -3
  4. data/lib/webruby/environment.rb +1 -0
  5. data/lib/webruby/rake/files.rake +22 -22
  6. data/lib/webruby/rake/general.rake +0 -1
  7. data/lib/webruby/utility.rb +2 -0
  8. data/modules/emscripten/AUTHORS +12 -1
  9. data/modules/emscripten/cmake/Platform/Emscripten.cmake +152 -15
  10. data/modules/emscripten/em++ +2 -0
  11. data/modules/emscripten/em++.bat +1 -1
  12. data/modules/emscripten/em-config.bat +1 -1
  13. data/modules/emscripten/emar.bat +1 -1
  14. data/modules/emscripten/emcc +233 -95
  15. data/modules/emscripten/emcc.bat +1 -1
  16. data/modules/emscripten/emconfigure.bat +1 -1
  17. data/modules/emscripten/emmake.bat +1 -1
  18. data/modules/emscripten/emranlib.bat +1 -1
  19. data/modules/emscripten/emscripten.py +221 -217
  20. data/modules/emscripten/package.json +7 -0
  21. data/modules/emscripten/src/analyzer.js +1437 -1385
  22. data/modules/emscripten/src/compiler.js +30 -6
  23. data/modules/emscripten/src/compiler_phase.html +33 -0
  24. data/modules/emscripten/src/fastLong.js +6 -6
  25. data/modules/emscripten/src/headless.js +47 -656
  26. data/modules/emscripten/src/headlessCanvas.js +618 -0
  27. data/modules/emscripten/src/intertyper.js +1038 -899
  28. data/modules/emscripten/src/jsifier.js +818 -714
  29. data/modules/emscripten/src/library.js +1794 -2968
  30. data/modules/emscripten/src/library_browser.js +81 -16
  31. data/modules/emscripten/src/library_egl.js +9 -3
  32. data/modules/emscripten/src/library_fs.js +1585 -0
  33. data/modules/emscripten/src/library_gl.js +445 -202
  34. data/modules/emscripten/src/library_glfw.js +4 -1
  35. data/modules/emscripten/src/library_glut.js +61 -13
  36. data/modules/emscripten/src/library_idbfs.js +216 -0
  37. data/modules/emscripten/src/library_memfs.js +279 -0
  38. data/modules/emscripten/src/library_nodefs.js +234 -0
  39. data/modules/emscripten/src/library_openal.js +131 -150
  40. data/modules/emscripten/src/library_path.js +3 -0
  41. data/modules/emscripten/src/library_sdl.js +499 -229
  42. data/modules/emscripten/src/library_sockfs.js +576 -0
  43. data/modules/emscripten/src/library_tty.js +146 -0
  44. data/modules/emscripten/src/modules.js +30 -35
  45. data/modules/emscripten/src/parseTools.js +356 -161
  46. data/modules/emscripten/src/postamble.js +76 -31
  47. data/modules/emscripten/src/preamble.js +271 -41
  48. data/modules/emscripten/src/proxyClient.js +82 -0
  49. data/modules/emscripten/src/proxyWorker.js +143 -0
  50. data/modules/emscripten/src/relooper/Relooper.cpp +60 -24
  51. data/modules/emscripten/src/relooper/Relooper.h +3 -2
  52. data/modules/emscripten/src/relooper/emscripten/glue.js +20 -10
  53. data/modules/emscripten/src/relooper/fuzzer.py +19 -10
  54. data/modules/emscripten/src/relooper/test.cpp +50 -50
  55. data/modules/emscripten/src/relooper/test.txt +147 -30
  56. data/modules/emscripten/src/relooper/test2.c +13 -13
  57. data/modules/emscripten/src/relooper/test2.txt +17 -3
  58. data/modules/emscripten/src/relooper/test3.c +7 -7
  59. data/modules/emscripten/src/relooper/test3.txt +36 -7
  60. data/modules/emscripten/src/relooper/test4.cpp +7 -7
  61. data/modules/emscripten/src/relooper/test4.txt +28 -7
  62. data/modules/emscripten/src/relooper/test5.cpp +6 -6
  63. data/modules/emscripten/src/relooper/test5.txt +34 -10
  64. data/modules/emscripten/src/relooper/test6.cpp +4 -4
  65. data/modules/emscripten/src/relooper/test6.txt +17 -3
  66. data/modules/emscripten/src/relooper/test_dead.cpp +2 -2
  67. data/modules/emscripten/src/relooper/test_debug.cpp +4 -4
  68. data/modules/emscripten/src/relooper/test_debug.txt +17 -3
  69. data/modules/emscripten/src/relooper/test_fuzz1.cpp +9 -9
  70. data/modules/emscripten/src/relooper/test_fuzz1.txt +45 -5
  71. data/modules/emscripten/src/relooper/test_fuzz2.cpp +4 -4
  72. data/modules/emscripten/src/relooper/test_fuzz2.txt +18 -1
  73. data/modules/emscripten/src/relooper/test_fuzz3.cpp +5 -5
  74. data/modules/emscripten/src/relooper/test_fuzz3.txt +16 -0
  75. data/modules/emscripten/src/relooper/test_fuzz4.cpp +5 -5
  76. data/modules/emscripten/src/relooper/test_fuzz4.txt +25 -3
  77. data/modules/emscripten/src/relooper/test_fuzz5.cpp +10 -10
  78. data/modules/emscripten/src/relooper/test_fuzz5.txt +49 -15
  79. data/modules/emscripten/src/relooper/test_fuzz6.cpp +92 -92
  80. data/modules/emscripten/src/relooper/test_fuzz6.txt +201 -18
  81. data/modules/emscripten/src/relooper/test_inf.cpp +184 -184
  82. data/modules/emscripten/src/relooper/test_inf.txt +1078 -332
  83. data/modules/emscripten/src/runtime.js +69 -45
  84. data/modules/emscripten/src/settings.js +48 -919
  85. data/modules/emscripten/src/shell.html +1 -1
  86. data/modules/emscripten/src/shell.js +14 -8
  87. data/modules/emscripten/src/shell_sharedlib.js +18 -1
  88. data/modules/emscripten/src/simd.js +958 -0
  89. data/modules/emscripten/src/struct_info.json +1045 -0
  90. data/modules/emscripten/src/utility.js +11 -0
  91. data/modules/emscripten/system/bin/sdl-config +13 -0
  92. data/modules/emscripten/system/include/compat/ctype.h +17 -0
  93. data/modules/emscripten/system/include/compat/malloc.h +48 -0
  94. data/modules/emscripten/system/include/compat/math.h +14 -0
  95. data/modules/emscripten/system/include/compat/netdb.h +22 -0
  96. data/modules/emscripten/system/include/compat/stdarg.h +16 -0
  97. data/modules/emscripten/system/include/compat/stdlib.h +16 -0
  98. data/modules/emscripten/system/include/compat/string.h +17 -0
  99. data/modules/emscripten/system/include/compat/sys/socketvar.h +14 -0
  100. data/modules/emscripten/system/include/compat/sys/stat.h +20 -0
  101. data/modules/emscripten/system/include/{libc → compat}/sys/timeb.h +3 -7
  102. data/modules/emscripten/system/include/compat/time.h +18 -0
  103. data/modules/emscripten/system/include/compat/unistd.h +16 -0
  104. data/modules/emscripten/system/include/compat/xlocale.h +19 -0
  105. data/modules/emscripten/system/include/emscripten/emscripten.h +48 -7
  106. data/modules/emscripten/system/include/emscripten/vector.h +6 -0
  107. data/modules/emscripten/system/include/libc/aio.h +69 -0
  108. data/modules/emscripten/system/include/libc/alloca.h +13 -13
  109. data/modules/emscripten/system/include/libc/ar.h +19 -63
  110. data/modules/emscripten/system/include/libc/arpa/ftp.h +35 -0
  111. data/modules/emscripten/system/include/libc/arpa/inet.h +36 -0
  112. data/modules/emscripten/system/include/libc/arpa/nameser.h +467 -0
  113. data/modules/emscripten/system/include/libc/arpa/nameser_compat.h +2 -0
  114. data/modules/emscripten/system/include/libc/arpa/telnet.h +251 -0
  115. data/modules/emscripten/system/include/libc/arpa/tftp.h +31 -0
  116. data/modules/emscripten/system/include/libc/assert.h +9 -36
  117. data/modules/emscripten/system/include/libc/bits/alltypes.h +397 -0
  118. data/modules/emscripten/system/include/libc/bits/endian.h +1 -0
  119. data/modules/emscripten/system/include/libc/bits/errno.h +134 -0
  120. data/modules/emscripten/system/include/libc/bits/fcntl.h +38 -0
  121. data/modules/emscripten/system/include/libc/bits/fenv.h +34 -0
  122. data/modules/emscripten/system/include/libc/bits/float.h +17 -0
  123. data/modules/emscripten/system/include/libc/bits/io.h +0 -0
  124. data/modules/emscripten/system/include/libc/bits/ioctl.h +197 -0
  125. data/modules/emscripten/system/include/libc/bits/ipc.h +14 -0
  126. data/modules/emscripten/system/include/libc/bits/limits.h +8 -0
  127. data/modules/emscripten/system/include/libc/bits/mman.h +62 -0
  128. data/modules/emscripten/system/include/libc/bits/msg.h +16 -0
  129. data/modules/emscripten/system/include/libc/bits/posix.h +2 -0
  130. data/modules/emscripten/system/include/libc/bits/reg.h +19 -0
  131. data/modules/emscripten/system/include/libc/bits/setjmp.h +1 -0
  132. data/modules/emscripten/system/include/libc/bits/shm.h +18 -0
  133. data/modules/emscripten/system/include/libc/bits/signal.h +112 -0
  134. data/modules/emscripten/system/include/libc/bits/socket.h +17 -0
  135. data/modules/emscripten/system/include/libc/bits/stat.h +22 -0
  136. data/modules/emscripten/system/include/libc/bits/statfs.h +7 -0
  137. data/modules/emscripten/system/include/libc/bits/stdarg.h +4 -0
  138. data/modules/emscripten/system/include/libc/bits/stdint.h +20 -0
  139. data/modules/emscripten/system/include/libc/bits/syscall.h +696 -0
  140. data/modules/emscripten/system/include/libc/bits/termios.h +160 -0
  141. data/modules/emscripten/system/include/libc/bits/user.h +48 -0
  142. data/modules/emscripten/system/include/libc/byteswap.h +26 -0
  143. data/modules/emscripten/system/include/libc/complex.h +55 -54
  144. data/modules/emscripten/system/include/libc/cpio.h +29 -0
  145. data/modules/emscripten/system/include/libc/crypt.h +20 -0
  146. data/modules/emscripten/system/include/libc/ctype.h +58 -187
  147. data/modules/emscripten/system/include/libc/dirent.h +69 -6
  148. data/modules/emscripten/system/include/libc/dlfcn.h +42 -0
  149. data/modules/emscripten/system/include/libc/elf.h +2555 -0
  150. data/modules/emscripten/system/include/libc/endian.h +80 -1
  151. data/modules/emscripten/system/include/libc/err.h +25 -0
  152. data/modules/emscripten/system/include/libc/errno.h +23 -7
  153. data/modules/emscripten/system/include/libc/fcntl.h +175 -1
  154. data/modules/emscripten/system/include/libc/features.h +32 -0
  155. data/modules/emscripten/system/include/libc/fenv.h +28 -0
  156. data/modules/emscripten/system/include/libc/float.h +34 -0
  157. data/modules/emscripten/system/include/libc/fnmatch.h +24 -50
  158. data/modules/emscripten/system/include/libc/ftw.h +42 -0
  159. data/modules/emscripten/system/include/libc/getopt.h +22 -187
  160. data/modules/emscripten/system/include/libc/glob.h +42 -83
  161. data/modules/emscripten/system/include/libc/grp.h +37 -79
  162. data/modules/emscripten/system/include/libc/iconv.h +18 -56
  163. data/modules/emscripten/system/include/libc/ifaddrs.h +24 -53
  164. data/modules/emscripten/system/include/libc/inttypes.h +208 -271
  165. data/modules/emscripten/system/include/libc/iso646.h +5 -28
  166. data/modules/emscripten/system/include/libc/langinfo.h +88 -316
  167. data/modules/emscripten/system/include/libc/lastlog.h +1 -0
  168. data/modules/emscripten/system/include/libc/libgen.h +5 -13
  169. data/modules/emscripten/system/include/libc/libintl.h +25 -0
  170. data/modules/emscripten/system/include/libc/limits.h +140 -149
  171. data/modules/emscripten/system/include/libc/link.h +54 -0
  172. data/modules/emscripten/system/include/libc/locale.h +72 -70
  173. data/modules/emscripten/system/include/libc/malloc.h +0 -169
  174. data/modules/emscripten/system/include/libc/math.h +393 -573
  175. data/modules/emscripten/system/include/libc/memory.h +1 -0
  176. data/modules/emscripten/system/include/libc/mntent.h +44 -0
  177. data/modules/emscripten/system/include/libc/monetary.h +23 -0
  178. data/modules/emscripten/system/include/libc/mqueue.h +36 -0
  179. data/modules/emscripten/system/include/libc/net/ethernet.h +55 -0
  180. data/modules/emscripten/system/include/libc/net/if.h +135 -0
  181. data/modules/emscripten/system/include/libc/net/if_arp.h +133 -0
  182. data/modules/emscripten/system/include/libc/net/route.h +124 -0
  183. data/modules/emscripten/system/include/libc/netdb.h +161 -0
  184. data/modules/emscripten/system/include/libc/netinet/ether.h +14 -0
  185. data/modules/emscripten/system/include/libc/netinet/icmp6.h +305 -0
  186. data/modules/emscripten/system/include/libc/netinet/if_ether.h +126 -0
  187. data/modules/emscripten/system/include/libc/netinet/in.h +336 -0
  188. data/modules/emscripten/system/include/libc/netinet/in_systm.h +9 -0
  189. data/modules/emscripten/system/include/libc/netinet/ip.h +186 -0
  190. data/modules/emscripten/system/include/libc/netinet/ip6.h +142 -0
  191. data/modules/emscripten/system/include/libc/netinet/ip_icmp.h +192 -0
  192. data/modules/emscripten/system/include/libc/netinet/tcp.h +71 -0
  193. data/modules/emscripten/system/include/libc/netinet/udp.h +35 -0
  194. data/modules/emscripten/system/include/libc/netpacket/packet.h +44 -0
  195. data/modules/emscripten/system/include/libc/nl_types.h +22 -0
  196. data/modules/emscripten/system/include/libc/paths.h +30 -5
  197. data/modules/emscripten/system/include/libc/poll.h +46 -0
  198. data/modules/emscripten/system/include/libc/pthread.h +191 -331
  199. data/modules/emscripten/system/include/libc/pty.h +18 -0
  200. data/modules/emscripten/system/include/libc/pwd.h +33 -62
  201. data/modules/emscripten/system/include/libc/readme.txt +2 -2
  202. data/modules/emscripten/system/include/libc/regex.h +53 -93
  203. data/modules/emscripten/system/include/libc/resolv.h +144 -0
  204. data/modules/emscripten/system/include/libc/sched.h +124 -89
  205. data/modules/emscripten/system/include/libc/search.h +40 -48
  206. data/modules/emscripten/system/include/libc/semaphore.h +35 -0
  207. data/modules/emscripten/system/include/libc/setjmp.h +35 -13
  208. data/modules/emscripten/system/include/libc/shadow.h +44 -0
  209. data/modules/emscripten/system/include/libc/signal.h +245 -20
  210. data/modules/emscripten/system/include/libc/spawn.h +74 -0
  211. data/modules/emscripten/system/include/libc/stdalign.h +15 -0
  212. data/modules/emscripten/system/include/libc/stdarg.h +18 -43
  213. data/modules/emscripten/system/include/libc/stdbool.h +14 -0
  214. data/modules/emscripten/system/include/libc/stddef.h +12 -58
  215. data/modules/emscripten/system/include/libc/stdint.h +82 -458
  216. data/modules/emscripten/system/include/libc/stdio.h +184 -679
  217. data/modules/emscripten/system/include/libc/stdio_ext.h +34 -0
  218. data/modules/emscripten/system/include/libc/stdlib.h +146 -205
  219. data/modules/emscripten/system/include/libc/stdnoreturn.h +5 -0
  220. data/modules/emscripten/system/include/libc/string.h +86 -89
  221. data/modules/emscripten/system/include/libc/strings.h +27 -27
  222. data/modules/emscripten/system/include/libc/stropts.h +139 -0
  223. data/modules/emscripten/system/include/libc/sys/acct.h +75 -0
  224. data/modules/emscripten/system/include/libc/sys/cachectl.h +22 -0
  225. data/modules/emscripten/system/include/libc/sys/dir.h +0 -8
  226. data/modules/emscripten/system/include/libc/sys/epoll.h +67 -0
  227. data/modules/emscripten/system/include/libc/sys/errno.h +2 -190
  228. data/modules/emscripten/system/include/libc/sys/eventfd.h +26 -0
  229. data/modules/emscripten/system/include/libc/sys/fcntl.h +2 -4
  230. data/modules/emscripten/system/include/libc/sys/file.h +20 -1
  231. data/modules/emscripten/system/include/libc/sys/fsuid.h +20 -0
  232. data/modules/emscripten/system/include/libc/sys/inotify.h +57 -0
  233. data/modules/emscripten/system/include/libc/sys/io.h +17 -0
  234. data/modules/emscripten/system/include/libc/sys/ioctl.h +14 -0
  235. data/modules/emscripten/system/include/libc/sys/ipc.h +42 -0
  236. data/modules/emscripten/system/include/{sys/sysctl.h → libc/sys/klog.h} +4 -4
  237. data/modules/emscripten/system/include/libc/sys/mman.h +55 -0
  238. data/modules/emscripten/system/include/libc/sys/mount.h +72 -0
  239. data/modules/emscripten/system/include/libc/sys/msg.h +52 -0
  240. data/modules/emscripten/system/include/libc/sys/mtio.h +188 -0
  241. data/modules/emscripten/system/include/libc/sys/param.h +29 -19
  242. data/modules/emscripten/system/include/libc/sys/personality.h +46 -0
  243. data/modules/emscripten/system/include/libc/sys/poll.h +2 -0
  244. data/modules/emscripten/system/include/libc/sys/prctl.h +101 -0
  245. data/modules/emscripten/system/include/libc/sys/procfs.h +65 -0
  246. data/modules/emscripten/system/include/libc/sys/ptrace.h +96 -0
  247. data/modules/emscripten/system/include/libc/sys/reboot.h +20 -0
  248. data/modules/emscripten/system/include/libc/sys/reg.h +9 -0
  249. data/modules/emscripten/system/include/libc/sys/resource.h +89 -45
  250. data/modules/emscripten/system/include/libc/sys/select.h +42 -0
  251. data/modules/emscripten/system/include/libc/sys/sem.h +82 -0
  252. data/modules/emscripten/system/include/libc/sys/sendfile.h +22 -0
  253. data/modules/emscripten/system/include/libc/sys/shm.h +61 -0
  254. data/modules/emscripten/system/include/libc/sys/signal.h +1 -315
  255. data/modules/emscripten/system/include/libc/sys/signalfd.h +44 -0
  256. data/modules/emscripten/system/include/libc/sys/socket.h +299 -0
  257. data/modules/emscripten/system/include/libc/sys/stat.h +95 -204
  258. data/modules/emscripten/system/include/libc/sys/statfs.h +32 -0
  259. data/modules/emscripten/system/include/libc/sys/statvfs.h +57 -0
  260. data/modules/emscripten/system/include/libc/sys/stropts.h +1 -0
  261. data/modules/emscripten/system/include/libc/sys/swap.h +21 -0
  262. data/modules/emscripten/system/include/libc/sys/syscall.h +6 -0
  263. data/modules/emscripten/system/include/libc/sys/sysctl.h +17 -0
  264. data/modules/emscripten/system/include/libc/sys/sysinfo.h +36 -0
  265. data/modules/emscripten/system/include/libc/sys/syslog.h +1 -0
  266. data/modules/emscripten/system/include/libc/sys/sysmacros.h +15 -0
  267. data/modules/emscripten/system/include/libc/sys/termios.h +2 -280
  268. data/modules/emscripten/system/include/libc/sys/time.h +40 -68
  269. data/modules/emscripten/system/include/libc/sys/timerfd.h +24 -0
  270. data/modules/emscripten/system/include/libc/sys/times.h +14 -16
  271. data/modules/emscripten/system/include/libc/sys/timex.h +98 -0
  272. data/modules/emscripten/system/include/libc/sys/ttydefaults.h +34 -92
  273. data/modules/emscripten/system/include/libc/sys/types.h +87 -481
  274. data/modules/emscripten/system/include/libc/sys/ucontext.h +1 -0
  275. data/modules/emscripten/system/include/libc/sys/uio.h +48 -0
  276. data/modules/emscripten/system/include/libc/sys/un.h +32 -0
  277. data/modules/emscripten/system/include/libc/sys/user.h +16 -0
  278. data/modules/emscripten/system/include/libc/sys/utsname.h +30 -0
  279. data/modules/emscripten/system/include/libc/sys/vfs.h +1 -0
  280. data/modules/emscripten/system/include/libc/sys/wait.h +41 -26
  281. data/modules/emscripten/system/include/libc/sys/xattr.h +30 -0
  282. data/modules/emscripten/system/include/libc/syscall.h +1 -0
  283. data/modules/emscripten/system/include/libc/sysexits.h +21 -0
  284. data/modules/emscripten/system/include/libc/syslog.h +104 -0
  285. data/modules/emscripten/system/include/libc/tar.h +27 -33
  286. data/modules/emscripten/system/include/libc/termios.h +40 -1
  287. data/modules/emscripten/system/include/libc/tgmath.h +270 -0
  288. data/modules/emscripten/system/include/libc/time.h +96 -237
  289. data/modules/emscripten/system/include/libc/ucontext.h +25 -0
  290. data/modules/emscripten/system/include/libc/ulimit.h +17 -0
  291. data/modules/emscripten/system/include/libc/unistd.h +517 -4
  292. data/modules/emscripten/system/include/libc/utime.h +15 -3
  293. data/modules/emscripten/system/include/libc/utmp.h +40 -1
  294. data/modules/emscripten/system/include/libc/utmpx.h +58 -0
  295. data/modules/emscripten/system/include/libc/values.h +39 -0
  296. data/modules/emscripten/system/include/libc/wchar.h +164 -175
  297. data/modules/emscripten/system/include/libc/wctype.h +67 -37
  298. data/modules/emscripten/system/include/libc/wordexp.h +31 -42
  299. data/modules/emscripten/system/include/libcxx/__locale +6 -6
  300. data/modules/emscripten/system/include/libcxx/locale +1 -1
  301. data/modules/emscripten/system/lib/libc/musl/readme.txt +9 -1
  302. data/modules/emscripten/system/lib/libc/musl/src/internal/locale_impl.h +5 -0
  303. data/modules/emscripten/system/lib/libc/musl/src/internal/stdio_impl.h +92 -0
  304. data/modules/emscripten/system/lib/libc/musl/src/locale/big5.h +1085 -0
  305. data/modules/emscripten/system/lib/libc/musl/src/locale/codepages.h +238 -0
  306. data/modules/emscripten/system/lib/libc/musl/src/locale/gb18030.h +1836 -0
  307. data/modules/emscripten/system/lib/libc/musl/src/locale/hkscs.h +390 -0
  308. data/modules/emscripten/system/lib/libc/musl/src/locale/iconv.c +454 -0
  309. data/modules/emscripten/system/lib/libc/musl/src/locale/iswalnum_l.c +6 -0
  310. data/modules/emscripten/system/lib/libc/musl/src/locale/iswalpha_l.c +6 -0
  311. data/modules/emscripten/system/lib/libc/musl/src/locale/iswblank_l.c +6 -0
  312. data/modules/emscripten/system/lib/libc/musl/src/locale/iswcntrl_l.c +6 -0
  313. data/modules/emscripten/system/lib/libc/musl/src/locale/iswctype_l.c +9 -0
  314. data/modules/emscripten/system/lib/libc/musl/src/locale/iswdigit_l.c +6 -0
  315. data/modules/emscripten/system/lib/libc/musl/src/locale/iswgraph_l.c +6 -0
  316. data/modules/emscripten/system/lib/libc/musl/src/locale/iswlower_l.c +6 -0
  317. data/modules/emscripten/system/lib/libc/musl/src/locale/iswprint_l.c +6 -0
  318. data/modules/emscripten/system/lib/libc/musl/src/locale/iswpunct_l.c +6 -0
  319. data/modules/emscripten/system/lib/libc/musl/src/locale/iswspace_l.c +6 -0
  320. data/modules/emscripten/system/lib/libc/musl/src/locale/iswupper_l.c +6 -0
  321. data/modules/emscripten/system/lib/libc/musl/src/locale/iswxdigit_l.c +6 -0
  322. data/modules/emscripten/system/lib/libc/musl/src/locale/jis0208.h +550 -0
  323. data/modules/emscripten/system/lib/libc/musl/src/locale/ksc.h +640 -0
  324. data/modules/emscripten/system/lib/libc/musl/src/locale/legacychars.h +39 -0
  325. data/modules/emscripten/system/lib/libc/musl/src/locale/strfmon.c +101 -0
  326. data/modules/emscripten/system/lib/libc/musl/src/locale/strxfrm.c +18 -0
  327. data/modules/emscripten/system/lib/libc/musl/src/locale/towctrans_l.c +6 -0
  328. data/modules/emscripten/system/lib/libc/musl/src/locale/towlower_l.c +9 -0
  329. data/modules/emscripten/system/lib/libc/musl/src/locale/towupper_l.c +9 -0
  330. data/modules/emscripten/system/lib/libc/musl/src/locale/wcscoll.c +16 -0
  331. data/modules/emscripten/system/lib/libc/musl/src/locale/wcscoll_l.c +6 -0
  332. data/modules/emscripten/system/lib/libc/musl/src/locale/wcsxfrm.c +21 -0
  333. data/modules/emscripten/system/lib/libc/musl/src/locale/wcsxfrm_l.c +6 -0
  334. data/modules/emscripten/system/lib/libc/musl/src/locale/wctrans_l.c +6 -0
  335. data/modules/emscripten/system/lib/libc/musl/src/locale/wctype_l.c +9 -0
  336. data/modules/emscripten/system/lib/libc/musl/src/stdio/fwprintf.c +13 -0
  337. data/modules/emscripten/system/lib/libc/musl/src/stdio/swprintf.c +14 -0
  338. data/modules/emscripten/system/lib/libc/musl/src/stdio/vfwprintf.c +361 -0
  339. data/modules/emscripten/system/lib/libc/musl/src/stdio/vswprintf.c +53 -0
  340. data/modules/emscripten/system/lib/libc/musl/src/stdio/vwprintf.c +7 -0
  341. data/modules/emscripten/system/lib/libc/musl/src/stdio/wprintf.c +13 -0
  342. data/modules/emscripten/system/lib/libcextra.symbols +44 -0
  343. data/modules/emscripten/system/lib/libcxx/exception.cpp +3 -3
  344. data/modules/emscripten/system/lib/libcxx/locale.cpp +12 -12
  345. data/modules/emscripten/system/lib/libcxxabi/src/cxa_new_delete.cpp +1 -1
  346. data/modules/emscripten/tools/asm_module.py +2 -0
  347. data/modules/emscripten/tools/autodebugger.py +3 -1
  348. data/modules/emscripten/tools/eliminator/asm-eliminator-test-output.js +0 -4835
  349. data/modules/emscripten/tools/eliminator/asm-eliminator-test.js +0 -6495
  350. data/modules/emscripten/tools/file_packager.py +53 -56
  351. data/modules/emscripten/tools/find_bigfuncs.py +2 -2
  352. data/modules/emscripten/tools/find_bigvars.py +24 -0
  353. data/modules/emscripten/tools/gen_struct_info.py +509 -0
  354. data/modules/emscripten/tools/gen_struct_info.pyc +0 -0
  355. data/modules/emscripten/tools/js-optimizer.js +177 -86
  356. data/modules/emscripten/tools/js_optimizer.py +54 -19
  357. data/modules/emscripten/tools/js_optimizer.pyc +0 -0
  358. data/modules/emscripten/tools/jsrun.py +17 -7
  359. data/modules/emscripten/tools/jsrun.pyc +0 -0
  360. data/modules/emscripten/tools/response_file.py +2 -2
  361. data/modules/emscripten/tools/response_file.pyc +0 -0
  362. data/modules/emscripten/tools/shared.py +257 -123
  363. data/modules/emscripten/tools/shared.pyc +0 -0
  364. data/modules/emscripten/tools/source-maps/sourcemapper.js +37 -6
  365. data/modules/emscripten/tools/tempfiles.py +1 -0
  366. data/modules/emscripten/tools/tempfiles.pyc +0 -0
  367. data/modules/emscripten/tools/test-js-optimizer-asm-minlast-output.js +2 -0
  368. data/modules/emscripten/tools/test-js-optimizer-asm-minlast.js +8 -0
  369. data/modules/emscripten/tools/test-js-optimizer-asm-outline1-output.js +412 -169
  370. data/modules/emscripten/tools/test-js-optimizer-asm-outline1.js +88 -0
  371. data/modules/emscripten/tools/test-js-optimizer-asm-outline2-output.js +311 -265
  372. data/modules/emscripten/tools/test-js-optimizer-asm-pre-output.js +0 -20
  373. data/modules/emscripten/tools/test-js-optimizer-asm-pre.js +0 -21
  374. data/modules/emscripten/tools/test-js-optimizer-asm-regs.js +2 -2
  375. data/modules/emscripten/tools/test-js-optimizer-regs-output.js +8 -8
  376. data/modules/emscripten/tools/test-js-optimizer-regs.js +1 -1
  377. data/modules/emscripten/tools/validate_asmjs.py +82 -0
  378. data/modules/mruby/Rakefile +2 -2
  379. data/modules/mruby/include/mruby/class.h +2 -2
  380. data/modules/mruby/include/mruby/compile.h +12 -4
  381. data/modules/mruby/include/mruby/data.h +8 -3
  382. data/modules/mruby/include/mruby/debug.h +65 -0
  383. data/modules/mruby/include/mruby/dump.h +10 -2
  384. data/modules/mruby/include/mruby/irep.h +1 -0
  385. data/modules/mruby/include/mruby/string.h +2 -1
  386. data/modules/mruby/include/mruby/value.h +20 -13
  387. data/modules/mruby/include/mruby/variable.h +1 -0
  388. data/modules/mruby/include/mruby.h +5 -6
  389. data/modules/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +6 -4
  390. data/modules/mruby/mrbgems/mruby-math/src/math.c +4 -0
  391. data/modules/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c +1 -1
  392. data/modules/mruby/mrbgems/mruby-proc-ext/src/proc.c +1 -1
  393. data/modules/mruby/mrbgems/mruby-random/src/random.c +1 -4
  394. data/modules/mruby/mrbgems/mruby-string-ext/src/string.c +25 -16
  395. data/modules/mruby/mrbgems/mruby-string-ext/test/string.rb +4 -0
  396. data/modules/mruby/mrbgems/mruby-struct/src/struct.c +1 -1
  397. data/modules/mruby/mrbgems/mruby-symbol-ext/mrblib/symbol.rb +51 -0
  398. data/modules/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb +22 -0
  399. data/modules/mruby/mrbgems/mruby-time/src/time.c +38 -60
  400. data/modules/mruby/mrblib/class.rb +2 -2
  401. data/modules/mruby/src/backtrace.c +96 -23
  402. data/modules/mruby/src/class.c +43 -41
  403. data/modules/mruby/src/codegen.c +52 -46
  404. data/modules/mruby/src/debug.c +214 -0
  405. data/modules/mruby/src/dump.c +245 -17
  406. data/modules/mruby/src/error.c +14 -6
  407. data/modules/mruby/src/etc.c +17 -10
  408. data/modules/mruby/src/gc.c +9 -9
  409. data/modules/mruby/src/kernel.c +1 -1
  410. data/modules/mruby/src/load.c +137 -1
  411. data/modules/mruby/src/object.c +1 -1
  412. data/modules/mruby/src/parse.y +162 -37
  413. data/modules/mruby/src/state.c +2 -0
  414. data/modules/mruby/src/string.c +28 -19
  415. data/modules/mruby/src/symbol.c +0 -1
  416. data/modules/mruby/src/variable.c +12 -15
  417. data/modules/mruby/src/vm.c +38 -22
  418. data/modules/mruby/tasks/mrbgem_spec.rake +6 -4
  419. data/modules/mruby/tasks/mrbgems_test.rake +9 -9
  420. data/modules/mruby/tasks/mruby_build_gem.rake +9 -0
  421. data/modules/mruby/tasks/toolchains/androideabi.rake +2 -0
  422. data/modules/mruby/test/driver.c +3 -3
  423. data/modules/mruby/test/t/array.rb +13 -0
  424. data/modules/mruby/test/t/class.rb +28 -0
  425. data/modules/mruby/test/t/exception.rb +10 -0
  426. data/modules/mruby/test/t/literals.rb +50 -0
  427. data/modules/mruby/test/t/module.rb +22 -0
  428. data/modules/mruby/test/t/proc.rb +37 -0
  429. data/modules/mruby/test/t/string.rb +20 -21
  430. data/modules/mruby/tools/mrbc/mrbc.c +2 -4
  431. data/scripts/gen_post.rb +1 -0
  432. data/scripts/gen_require.rb +107 -0
  433. data/templates/minimal/Rakefile +20 -0
  434. metadata +210 -88
  435. data/driver/main.c +0 -40
  436. data/modules/emscripten/cmake/Platform/Emscripten_unix.cmake +0 -24
  437. data/modules/emscripten/emlibtool +0 -11
  438. data/modules/emscripten/emlibtool.bat +0 -2
  439. data/modules/emscripten/src/framework.js +0 -257
  440. data/modules/emscripten/system/include/bsd/float.h +0 -91
  441. data/modules/emscripten/system/include/bsd/readme.txt +0 -2
  442. data/modules/emscripten/system/include/bsd/sys/mman.h +0 -180
  443. data/modules/emscripten/system/include/bsd/sys/utsname.h +0 -70
  444. data/modules/emscripten/system/include/dlfcn.h +0 -31
  445. data/modules/emscripten/system/include/err.h +0 -95
  446. data/modules/emscripten/system/include/features.h +0 -3
  447. data/modules/emscripten/system/include/libc/_ansi.h +0 -135
  448. data/modules/emscripten/system/include/libc/_syslist.h +0 -40
  449. data/modules/emscripten/system/include/libc/argz.h +0 -33
  450. data/modules/emscripten/system/include/libc/envlock.h +0 -15
  451. data/modules/emscripten/system/include/libc/envz.h +0 -16
  452. data/modules/emscripten/system/include/libc/fastmath.h +0 -13
  453. data/modules/emscripten/system/include/libc/ieeefp.h +0 -256
  454. data/modules/emscripten/system/include/libc/machine/_default_types.h +0 -121
  455. data/modules/emscripten/system/include/libc/machine/_types.h +0 -8
  456. data/modules/emscripten/system/include/libc/machine/ansi.h +0 -1
  457. data/modules/emscripten/system/include/libc/machine/endian.h +0 -31
  458. data/modules/emscripten/system/include/libc/machine/fastmath.h +0 -100
  459. data/modules/emscripten/system/include/libc/machine/ieeefp.h +0 -376
  460. data/modules/emscripten/system/include/libc/machine/malloc.h +0 -8
  461. data/modules/emscripten/system/include/libc/machine/param.h +0 -1
  462. data/modules/emscripten/system/include/libc/machine/setjmp-dj.h +0 -43
  463. data/modules/emscripten/system/include/libc/machine/setjmp.h +0 -361
  464. data/modules/emscripten/system/include/libc/machine/stdlib.h +0 -8
  465. data/modules/emscripten/system/include/libc/machine/termios.h +0 -1
  466. data/modules/emscripten/system/include/libc/machine/time.h +0 -19
  467. data/modules/emscripten/system/include/libc/machine/types.h +0 -30
  468. data/modules/emscripten/system/include/libc/newlib.h +0 -2
  469. data/modules/emscripten/system/include/libc/process.h +0 -44
  470. data/modules/emscripten/system/include/libc/reent.h +0 -183
  471. data/modules/emscripten/system/include/libc/regdef.h +0 -7
  472. data/modules/emscripten/system/include/libc/sys/_default_fcntl.h +0 -223
  473. data/modules/emscripten/system/include/libc/sys/_types.h +0 -93
  474. data/modules/emscripten/system/include/libc/sys/cdefs.h +0 -123
  475. data/modules/emscripten/system/include/libc/sys/config.h +0 -255
  476. data/modules/emscripten/system/include/libc/sys/custom_file.h +0 -2
  477. data/modules/emscripten/system/include/libc/sys/dirent.h +0 -58
  478. data/modules/emscripten/system/include/libc/sys/features.h +0 -212
  479. data/modules/emscripten/system/include/libc/sys/iconvnls.h +0 -77
  480. data/modules/emscripten/system/include/libc/sys/lock.h +0 -24
  481. data/modules/emscripten/system/include/libc/sys/queue.h +0 -471
  482. data/modules/emscripten/system/include/libc/sys/reent.h +0 -843
  483. data/modules/emscripten/system/include/libc/sys/sched.h +0 -67
  484. data/modules/emscripten/system/include/libc/sys/stdio.h +0 -27
  485. data/modules/emscripten/system/include/libc/sys/string.h +0 -2
  486. data/modules/emscripten/system/include/libc/sys/syslimits.h +0 -65
  487. data/modules/emscripten/system/include/libc/sys/unistd.h +0 -514
  488. data/modules/emscripten/system/include/libc/sys/utime.h +0 -26
  489. data/modules/emscripten/system/include/libc/unctrl.h +0 -46
  490. data/modules/emscripten/system/include/memory.h +0 -10
  491. data/modules/emscripten/system/include/mntent.h +0 -23
  492. data/modules/emscripten/system/include/net/arpa/inet.h +0 -32
  493. data/modules/emscripten/system/include/net/arpa/nameser.h +0 -535
  494. data/modules/emscripten/system/include/net/arpa/nameser_compat.h +0 -187
  495. data/modules/emscripten/system/include/net/if.h +0 -106
  496. data/modules/emscripten/system/include/net/netinet/in.h +0 -230
  497. data/modules/emscripten/system/include/net/netinet/tcp.h +0 -246
  498. data/modules/emscripten/system/include/net/resolv.h +0 -389
  499. data/modules/emscripten/system/include/netdb.h +0 -130
  500. data/modules/emscripten/system/include/nl_types.h +0 -19
  501. data/modules/emscripten/system/include/poll.h +0 -3
  502. data/modules/emscripten/system/include/pty.h +0 -6
  503. data/modules/emscripten/system/include/semaphore.h +0 -31
  504. data/modules/emscripten/system/include/spawn.h +0 -105
  505. data/modules/emscripten/system/include/stdbool.h +0 -16
  506. data/modules/emscripten/system/include/sys/bitypes.h +0 -3
  507. data/modules/emscripten/system/include/sys/io.h +0 -14
  508. data/modules/emscripten/system/include/sys/ioctl.h +0 -78
  509. data/modules/emscripten/system/include/sys/poll.h +0 -31
  510. data/modules/emscripten/system/include/sys/select.h +0 -16
  511. data/modules/emscripten/system/include/sys/sendfile.h +0 -16
  512. data/modules/emscripten/system/include/sys/socket.h +0 -247
  513. data/modules/emscripten/system/include/sys/socketvar.h +0 -3
  514. data/modules/emscripten/system/include/sys/statvfs.h +0 -32
  515. data/modules/emscripten/system/include/sys/uio.h +0 -22
  516. data/modules/emscripten/system/include/sys/un.h +0 -66
  517. data/modules/emscripten/system/include/sysexits.h +0 -108
  518. data/modules/emscripten/system/include/xlocale.h +0 -47
@@ -3,682 +3,643 @@
3
3
  // LLVM assembly => internal intermediate representation, which is ready
4
4
  // to be processed by the later stages.
5
5
 
6
- var tokenizer; // TODO: Clean this up/out
7
- // XXX In particular, this closes over the substrate, which can keep stuff in memory, which is bad
6
+ var fastPaths = 0, slowPaths = 0;
7
+
8
+ var tokenCache = {};
9
+ [',', '{', '}', 'i32', 'label', ';', '4', '0', '1', '2', '255', 'align', 'i8*', 'i8', 'i16', 'getelementptr', 'inbounds', 'unnamed_addr', 'x', 'load', 'preds', 'br', 'i32*', 'i1', 'store', '<label>', 'constant', 'c', 'private', 'null', 'internal', 'to', 'bitcast', 'define', 'nounwind', 'nocapture', '%this', 'call', '...'].forEach(function(text) { tokenCache[text] = { text: text } });
10
+
11
+ //var tokenCacheMisses = {};
12
+
13
+ // Line tokenizer
8
14
  function tokenize(text) {
9
- return tokenizer.processItem({ lineText: text }, true);
15
+ var tokens = [];
16
+ var quotes = 0;
17
+ var lastToken = null;
18
+ var enclosers = {
19
+ '[': 0,
20
+ ']': '[',
21
+ '(': 0,
22
+ ')': '(',
23
+ '<': 0,
24
+ '>': '<',
25
+ '{': 0,
26
+ '}': '{',
27
+ };
28
+ var totalEnclosing = 0;
29
+ function makeToken(text) {
30
+ if (text.length == 0) return;
31
+ // merge *..* into last token
32
+ if (lastToken && text[0] === '*') {
33
+ //assert(/^\**$/.test(text));
34
+ //assert(!(lastToken.text in tokenCache));
35
+ lastToken.text += text;
36
+ return;
37
+ }
38
+
39
+ var cached = tokenCache[text];
40
+ if (cached) {
41
+ //assert(cached.text === text);
42
+ tokens.push(cached);
43
+ lastToken = cached;
44
+ return;
45
+ }
46
+ //tokenCacheMisses[text] = (misses[text] || 0) + 1;
47
+
48
+ var token = {
49
+ text: text
50
+ };
51
+ if (text[0] in enclosers) {
52
+ token.tokens = tokenize(text.substr(1, text.length-2));
53
+ token.type = text[0];
54
+ }
55
+ // merge function definitions together
56
+ if (lastToken && isType(lastToken.text) && isFunctionDef(token)) {
57
+ if (lastToken.text in tokenCache) {
58
+ // create a copy of the cached value
59
+ lastToken = tokens[tokens.length-1] = { text: lastToken.text };
60
+ }
61
+ lastToken.text += ' ' + text;
62
+ } else {
63
+ tokens.push(token);
64
+ lastToken = token;
65
+ }
66
+ }
67
+ // Split using meaningful characters
68
+ var lineText = text + ' ';
69
+ var re = /[\[\]\(\)<>{}, "]/g;
70
+ var segments = lineText.split(re);
71
+ segments.pop();
72
+ var len = segments.length;
73
+ var i = -1;
74
+ var start = 0;
75
+ var segment, letter, last;
76
+ if (lineText[0] === '}') {
77
+ tokens.push(tokenCache['}']); // end of function and landingpads have an unmatched {
78
+ }
79
+ for (var s = 0; s < len; s++) {
80
+ segment = segments[s];
81
+ i += segment.length + 1;
82
+ last = letter;
83
+ letter = lineText[i];
84
+ switch (letter) {
85
+ case ' ':
86
+ if (totalEnclosing == 0 && quotes == 0) {
87
+ makeToken(lineText.substring(start, i));
88
+ start = i+1;
89
+ }
90
+ break;
91
+ case '"':
92
+ if (totalEnclosing == 0) {
93
+ if (quotes == 0) {
94
+ if (start === i-1 && (lineText[start] == '@' || lineText[start] == '%')) {
95
+ } else {
96
+ makeToken(lineText.substring(start, i));
97
+ start = i;
98
+ }
99
+ } else {
100
+ makeToken(lineText.substring(start, i+1));
101
+ start = i+1;
102
+ }
103
+ }
104
+ quotes = 1-quotes;
105
+ break;
106
+ case ',':
107
+ if (totalEnclosing == 0 && quotes == 0) {
108
+ makeToken(lineText.substring(start, i));
109
+ start = i+1;
110
+ tokens.push(tokenCache[',']);
111
+ }
112
+ break;
113
+ default:
114
+ assert(letter in enclosers);
115
+ if (quotes) {
116
+ break;
117
+ }
118
+ if (letter in ENCLOSER_STARTERS) {
119
+ if (totalEnclosing == 0) {
120
+ makeToken(lineText.substring(start, i));
121
+ start = i;
122
+ }
123
+ enclosers[letter]++;
124
+ totalEnclosing++;
125
+ } else {
126
+ enclosers[enclosers[letter]]--;
127
+ totalEnclosing--;
128
+ if (totalEnclosing == 0) {
129
+ makeToken(lineText.substring(start, i+1));
130
+ start = i+1;
131
+ }
132
+ }
133
+ }
134
+ }
135
+ if (last === '{') {
136
+ tokens.push(tokenCache['{']); // beginning of function and landingpads have an unmatched {
137
+ }
138
+ return tokens;
10
139
  }
11
140
 
12
141
  // Handy sets
13
142
 
14
- var ENCLOSER_STARTERS = set('[', '(', '<');
143
+ var ENCLOSER_STARTERS = set('[', '(', '<', '{');
15
144
  var ENCLOSER_ENDERS = {
16
145
  '[': ']',
17
146
  '(': ')',
18
- '<': '>'
147
+ '<': '>',
148
+ '{': '}'
19
149
  };
20
150
  var ZEROINIT_UNDEF = set('zeroinitializer', 'undef');
21
151
  var NSW_NUW = set('nsw', 'nuw');
22
152
 
23
153
  // Intertyper
24
154
 
25
- function intertyper(data, sidePass, baseLineNums) {
155
+ function intertyper(lines, sidePass, baseLineNums) {
26
156
  var mainPass = !sidePass;
27
157
  baseLineNums = baseLineNums || [[0,0]]; // each pair [#0,#1] means "starting from line #0, the base line num is #1"
28
158
 
29
159
  dprint('framework', 'Big picture: Starting intertyper, main pass=' + mainPass);
30
160
 
31
- // Substrate
32
-
33
- var substrate = new Substrate('Intertyper');
161
+ var finalResults = [];
34
162
 
35
- // Line splitter. We break off some bunches of lines into unparsedBundles, which are
163
+ // Line splitter. We break off some bunches of lines into unparsed bundles, which are
36
164
  // parsed in separate passes later. This helps to keep memory usage low - we can start
37
165
  // from raw lines and end up with final JS for each function individually that way, instead
38
166
  // of intertyping them all, then analyzing them all, etc.
39
- substrate.addActor('LineSplitter', {
40
- processItem: function _lineSplitter(item) {
41
- var lines = item.llvmLines;
42
- var ret = [];
43
- var inContinual = false;
44
- var inFunction = false;
45
- var currFunctionLines;
46
- var currFunctionLineNum;
47
- var unparsedBundles = [];
48
- var unparsedTypes, unparsedGlobals;
49
- if (mainPass) {
50
- unparsedTypes = {
51
- intertype: 'unparsedTypes',
52
- lines: []
53
- };
54
- unparsedBundles.push(unparsedTypes);
55
- unparsedGlobals = {
56
- intertype: 'unparsedGlobals',
57
- lines: []
58
- };
59
- unparsedBundles.push(unparsedGlobals);
60
- }
61
- var baseLineNumPosition = 0;
62
- for (var i = 0; i < lines.length; i++) {
63
- var line = lines[i];
64
- if (singlePhase) lines[i] = null; // lines may be very very large. Allow GCing to occur in the loop by releasing refs here
167
+ function lineSplitter() {
168
+ var ret = [];
169
+ var inContinual = false;
170
+ var inFunction = false;
171
+ var currFunctionLines;
172
+ var currFunctionLineNum;
173
+ var unparsedTypes, unparsedGlobals;
174
+ if (mainPass) {
175
+ unparsedTypes = {
176
+ intertype: 'unparsedTypes',
177
+ lines: []
178
+ };
179
+ finalResults.push(unparsedTypes);
180
+ unparsedGlobals = {
181
+ intertype: 'unparsedGlobals',
182
+ lines: []
183
+ };
184
+ finalResults.push(unparsedGlobals);
185
+ }
186
+ var baseLineNumPosition = 0;
187
+ for (var i = 0; i < lines.length; i++) {
188
+ var line = lines[i];
189
+ if (singlePhase) lines[i] = null; // lines may be very very large. Allow GCing to occur in the loop by releasing refs here
65
190
 
66
- while (baseLineNumPosition < baseLineNums.length-1 && i >= baseLineNums[baseLineNumPosition+1][0]) {
67
- baseLineNumPosition++;
68
- }
191
+ while (baseLineNumPosition < baseLineNums.length-1 && i >= baseLineNums[baseLineNumPosition+1][0]) {
192
+ baseLineNumPosition++;
193
+ }
69
194
 
70
- if (mainPass && (line[0] == '%' || line[0] == '@')) {
71
- // If this isn't a type, it's a global variable, make a note of the information now, we will need it later
72
- var parts = line.split(' = ');
73
- assert(parts.length >= 2);
74
- var left = parts[0], right = parts.slice(1).join(' = ');
75
- var testType = /^type .*/.exec(right);
76
- if (!testType) {
77
- var globalIdent = toNiceIdent(left);
78
- var testAlias = /^(hidden )?alias .*/.exec(right);
79
- Variables.globals[globalIdent] = {
80
- name: globalIdent,
81
- alias: !!testAlias,
82
- impl: VAR_EMULATED
83
- };
84
- unparsedGlobals.lines.push(line);
85
- } else {
86
- unparsedTypes.lines.push(line);
87
- }
88
- continue;
89
- }
90
- if (mainPass && /^define .*/.test(line)) {
91
- inFunction = true;
92
- currFunctionLines = [];
93
- currFunctionLineNum = i + 1;
195
+ if (mainPass && (line[0] == '%' || line[0] == '@')) {
196
+ // If this isn't a type, it's a global variable, make a note of the information now, we will need it later
197
+ var parts = line.split(' = ');
198
+ assert(parts.length >= 2);
199
+ var left = parts[0], right = parts.slice(1).join(' = ');
200
+ var testType = /^type .*/.exec(right);
201
+ if (!testType) {
202
+ var globalIdent = toNiceIdent(left);
203
+ var testAlias = /^(hidden )?alias .*/.exec(right);
204
+ Variables.globals[globalIdent] = {
205
+ name: globalIdent,
206
+ alias: !!testAlias,
207
+ impl: VAR_EMULATED
208
+ };
209
+ unparsedGlobals.lines.push(line);
210
+ } else {
211
+ unparsedTypes.lines.push(line);
94
212
  }
95
- if (!inFunction || !mainPass) {
96
- if (inContinual || /^\ +(to|catch |filter |cleanup).*/.test(line)) {
97
- // to after invoke or landingpad second line
98
- ret.slice(-1)[0].lineText += line;
99
- if (/^\ +\]/.test(line)) { // end of llvm switch
100
- inContinual = false;
101
- }
102
- } else {
103
- ret.push({
104
- lineText: line,
105
- lineNum: i + 1 + baseLineNums[baseLineNumPosition][1] - baseLineNums[baseLineNumPosition][0]
106
- });
107
- if (/^\ +switch\ .*/.test(line)) {
108
- // beginning of llvm switch
109
- inContinual = true;
110
- }
213
+ continue;
214
+ }
215
+ if (mainPass && /^define .*/.test(line)) {
216
+ inFunction = true;
217
+ currFunctionLines = [];
218
+ currFunctionLineNum = i + 1;
219
+ }
220
+ if (!inFunction || !mainPass) {
221
+ if (inContinual || /^\ +(to|catch |filter |cleanup).*/.test(line)) {
222
+ // to after invoke or landingpad second line
223
+ ret.slice(-1)[0].lineText += line;
224
+ if (/^\ +\]/.test(line)) { // end of llvm switch
225
+ inContinual = false;
111
226
  }
112
227
  } else {
113
- currFunctionLines.push(line);
114
- }
115
- if (mainPass && /^}.*/.test(line)) {
116
- inFunction = false;
117
- if (mainPass) {
118
- var func = funcHeader.processItem(tokenizer.processItem({ lineText: currFunctionLines[0], lineNum: currFunctionLineNum }, true))[0];
119
-
120
- if (SKIP_STACK_IN_SMALL && /emscripten_autodebug/.exec(func.ident)) {
121
- warnOnce('Disabling SKIP_STACK_IN_SMALL because we are apparently processing autodebugger data');
122
- SKIP_STACK_IN_SMALL = 0;
123
- }
124
-
125
- var ident = toNiceIdent(func.ident);
126
- if (!(ident in DEAD_FUNCTIONS)) {
127
- unparsedBundles.push({
128
- intertype: 'unparsedFunction',
129
- // We need this early, to know basic function info - ident, params, varargs
130
- ident: ident,
131
- params: func.params,
132
- returnType: func.returnType,
133
- hasVarArgs: func.hasVarArgs,
134
- lineNum: currFunctionLineNum,
135
- lines: currFunctionLines
136
- });
137
- }
138
- currFunctionLines = [];
228
+ ret.push({
229
+ lineText: line,
230
+ lineNum: i + 1 + baseLineNums[baseLineNumPosition][1] - baseLineNums[baseLineNumPosition][0]
231
+ });
232
+ if (/^\ +switch\ .*/.test(line)) {
233
+ // beginning of llvm switch
234
+ inContinual = true;
139
235
  }
140
236
  }
237
+ } else {
238
+ currFunctionLines.push(line);
141
239
  }
142
- // We need lines beginning with ';' inside functions, because older LLVM versions generated labels that way. But when not
143
- // parsing functions, we can ignore all such lines and save some time that way.
144
- this.forwardItems(ret.filter(function(item) { return item.lineText && (item.lineText[0] != ';' || !mainPass); }), 'Tokenizer');
145
- return unparsedBundles;
146
- }
147
- });
240
+ if (mainPass && /^}.*/.test(line)) {
241
+ inFunction = false;
242
+ if (mainPass) {
243
+ var func = funcHeaderHandler({ tokens: tokenize(currFunctionLines[0], currFunctionLineNum) });
148
244
 
149
- // Line tokenizer
150
- tokenizer = substrate.addActor('Tokenizer', {
151
- processItem: function _tokenizer(item, inner) {
152
- //assert(item.lineNum != 40000);
153
- //if (item.lineNum) print(item.lineNum);
154
- var tokens = [];
155
- var quotes = 0;
156
- var lastToken = null;
157
- var CHUNKSIZE = 64; // How much forward to peek forward. Too much means too many string segments copied
158
- // Note: '{' is not an encloser, as its use in functions is split over many lines
159
- var enclosers = {
160
- '[': 0,
161
- ']': '[',
162
- '(': 0,
163
- ')': '(',
164
- '<': 0,
165
- '>': '<'
166
- };
167
- var totalEnclosing = 0;
168
- var that = this;
169
- function makeToken(text) {
170
- if (text.length == 0) return;
171
- // merge certain tokens
172
- if (lastToken && ( (lastToken.text == '%' && text[0] == '"') || /^\**$/.test(text) ) ) {
173
- lastToken.text += text;
174
- return;
175
- }
245
+ if (SKIP_STACK_IN_SMALL && /emscripten_autodebug/.exec(func.ident)) {
246
+ warnOnce('Disabling SKIP_STACK_IN_SMALL because we are apparently processing autodebugger data');
247
+ SKIP_STACK_IN_SMALL = 0;
248
+ }
176
249
 
177
- var token = {
178
- text: text
179
- };
180
- if (text[0] in enclosers) {
181
- token.item = that.processItem({
182
- lineText: text.substr(1, text.length-2)
183
- }, true);
184
- token.type = text[0];
185
- }
186
- // merge certain tokens
187
- if (lastToken && isType(lastToken.text) && isFunctionDef(token)) {
188
- lastToken.text += ' ' + text;
189
- } else if (lastToken && text[0] == '}') { // }, }*, etc.
190
- var openBrace = tokens.length-1;
191
- while (tokens[openBrace].text.substr(-1) != '{') openBrace --;
192
- token = combineTokens(tokens.slice(openBrace+1));
193
- tokens.splice(openBrace, tokens.length-openBrace+1);
194
- tokens.push(token);
195
- token.type = '{';
196
- token.text = '{ ' + token.text + ' }';
197
- var pointingLevelsToAdd = pointingLevels(text) - pointingLevels(token.text);
198
- while (pointingLevelsToAdd > 0) {
199
- token.text += '*';
200
- pointingLevelsToAdd--;
250
+ var ident = toNiceIdent(func.ident);
251
+ if (!(ident in DEAD_FUNCTIONS)) {
252
+ finalResults.push({
253
+ intertype: 'unparsedFunction',
254
+ // We need this early, to know basic function info - ident, params, varargs
255
+ ident: ident,
256
+ params: func.params,
257
+ returnType: func.returnType,
258
+ hasVarArgs: func.hasVarArgs,
259
+ lineNum: currFunctionLineNum,
260
+ lines: currFunctionLines
261
+ });
201
262
  }
202
- lastToken = token;
203
- } else {
204
- tokens.push(token);
205
- lastToken = token;
206
- }
207
- }
208
- // Split using meaningful characters
209
- var lineText = item.lineText + ' ';
210
- var re = /[\[\]\(\)<>, "]/g;
211
- var segments = lineText.split(re);
212
- segments.pop();
213
- var len = segments.length;
214
- var i = -1;
215
- var curr = '';
216
- var segment, letter;
217
- for (var s = 0; s < len; s++) {
218
- segment = segments[s];
219
- i += segment.length + 1;
220
- letter = lineText[i];
221
- curr += segment;
222
- switch (letter) {
223
- case ' ':
224
- if (totalEnclosing == 0 && quotes == 0) {
225
- makeToken(curr);
226
- curr = '';
227
- } else {
228
- curr += ' ';
229
- }
230
- break;
231
- case '"':
232
- if (totalEnclosing == 0) {
233
- if (quotes == 0) {
234
- if (curr == '@' || curr == '%') {
235
- curr += '"';
236
- } else {
237
- makeToken(curr);
238
- curr = '"';
239
- }
240
- } else {
241
- makeToken(curr + '"');
242
- curr = '';
243
- }
244
- } else {
245
- curr += '"';
246
- }
247
- quotes = 1-quotes;
248
- break;
249
- case ',':
250
- if (totalEnclosing == 0 && quotes == 0) {
251
- makeToken(curr);
252
- curr = '';
253
- tokens.push({ text: ',' });
254
- } else {
255
- curr += ',';
256
- }
257
- break;
258
- default:
259
- assert(letter in enclosers);
260
- if (quotes) {
261
- curr += letter;
262
- break;
263
- }
264
- if (letter in ENCLOSER_STARTERS) {
265
- if (totalEnclosing == 0) {
266
- makeToken(curr);
267
- curr = '';
268
- }
269
- curr += letter;
270
- enclosers[letter]++;
271
- totalEnclosing++;
272
- } else {
273
- enclosers[enclosers[letter]]--;
274
- totalEnclosing--;
275
- if (totalEnclosing == 0) {
276
- makeToken(curr + letter);
277
- curr = '';
278
- } else {
279
- curr += letter;
280
- }
281
- }
263
+ currFunctionLines = [];
282
264
  }
283
265
  }
284
- var newItem = {
285
- tokens: tokens,
286
- indent: lineText.search(/[^ ]/),
287
- lineNum: item.lineNum
288
- };
289
- if (inner) {
290
- return newItem;
291
- } else {
292
- this.forwardItem(newItem, 'Triager');
293
- }
294
- return null;
295
266
  }
296
- });
267
+ // We need lines beginning with ';' inside functions, because older LLVM versions generated labels that way. But when not
268
+ // parsing functions, we can ignore all such lines and save some time that way.
269
+ return ret.filter(function(item) { return item.lineText && (item.lineText[0] != ';' || !mainPass); });
270
+ }
297
271
 
298
- substrate.addActor('Triager', {
299
- processItem: function _triager(item) {
300
- function triage() {
301
- assert(!item.intertype);
302
- var token0Text = item.tokens[0].text;
303
- var token1Text = item.tokens[1] ? item.tokens[1].text : null;
304
- var tokensLength = item.tokens.length;
305
- if (item.indent === 2) {
306
- if (tokensLength >= 5 &&
307
- (token0Text == 'store' || token1Text == 'store'))
308
- return 'Store';
309
- if (tokensLength >= 3 && token0Text == 'br')
310
- return 'Branch';
311
- if (tokensLength >= 2 && token0Text == 'ret')
312
- return 'Return';
313
- if (tokensLength >= 2 && token0Text == 'switch')
314
- return 'Switch';
315
- if (token0Text == 'unreachable')
316
- return 'Unreachable';
317
- if (tokensLength >= 3 && token0Text == 'indirectbr')
318
- return 'IndirectBr';
319
- if (tokensLength >= 2 && token0Text == 'resume')
320
- return 'Resume';
321
- if (tokensLength >= 3 &&
322
- (token0Text == 'load' || token1Text == 'load'))
323
- return 'Load';
324
- if (tokensLength >= 3 &&
325
- token0Text in MATHOPS)
326
- return 'Mathops';
327
- if (tokensLength >= 3 && token0Text == 'bitcast')
328
- return 'Bitcast';
329
- if (tokensLength >= 3 && token0Text == 'getelementptr')
330
- return 'GEP';
331
- if (tokensLength >= 2 && token0Text == 'alloca')
332
- return 'Alloca';
333
- if (tokensLength >= 3 && token0Text == 'extractvalue')
334
- return 'ExtractValue';
335
- if (tokensLength >= 3 && token0Text == 'insertvalue')
336
- return 'InsertValue';
337
- if (tokensLength >= 3 && token0Text == 'phi')
338
- return 'Phi';
339
- if (tokensLength >= 3 && token0Text == 'va_arg')
340
- return 'va_arg';
341
- if (tokensLength >= 3 && token0Text == 'landingpad')
342
- return 'Landingpad';
343
- if (token0Text == 'fence')
344
- return '/dev/null';
345
- } else if (item.indent === 0) {
346
- if ((tokensLength >= 1 && token0Text.substr(-1) == ':') ||
347
- (tokensLength >= 3 && token1Text == '<label>') ||
348
- (tokensLength >= 2 && token1Text == ':'))
349
- return 'Label';
350
- if (tokensLength >= 4 && token0Text == 'declare')
351
- return 'External';
352
- if (tokensLength >= 3 && token1Text == '=')
353
- return 'Global';
354
- if (tokensLength >= 4 && token0Text == 'define' &&
355
- item.tokens.slice(-1)[0].text == '{')
356
- return 'FuncHeader';
357
- if (tokensLength >= 1 && token0Text == '}')
358
- return 'FuncEnd';
359
- if (token0Text == 'module' && token1Text == 'asm') {
360
- warn('Ignoring module asm: ' + item.tokens[2].text);
361
- return '/dev/null';
362
- }
363
- if (token0Text == 'attributes')
364
- return '/dev/null';
365
- }
366
- if (tokensLength >= 3 && (token0Text == 'call' || token1Text == 'call'))
367
- return 'Call';
368
- if (token0Text == 'target')
369
- return '/dev/null';
370
- if (token0Text == ';')
371
- return '/dev/null';
372
- if (tokensLength >= 3 && token0Text == 'invoke')
373
- return 'Invoke';
374
- if (tokensLength >= 3 && token0Text == 'atomicrmw' || token0Text == 'cmpxchg')
375
- return 'Atomic';
376
- throw 'Invalid token, cannot triage: ' + dump(item);
272
+ function triager(item) {
273
+ assert(!item.intertype);
274
+ var token0Text = item.tokens[0].text;
275
+ var token1Text = item.tokens[1] ? item.tokens[1].text : null;
276
+ var tokensLength = item.tokens.length;
277
+ if (item.indent === 2) {
278
+ if (tokensLength >= 5 &&
279
+ (token0Text == 'store' || token1Text == 'store'))
280
+ return storeHandler(item);
281
+ if (tokensLength >= 3 && token0Text == 'br')
282
+ return branchHandler(item);
283
+ if (tokensLength >= 2 && token0Text == 'ret')
284
+ return returnHandler(item);
285
+ if (tokensLength >= 2 && token0Text == 'switch')
286
+ return switchHandler(item);
287
+ if (token0Text == 'unreachable')
288
+ return unreachableHandler(item);
289
+ if (tokensLength >= 3 && token0Text == 'indirectbr')
290
+ return indirectBrHandler(item);
291
+ if (tokensLength >= 2 && token0Text == 'resume')
292
+ return resumeHandler(item);
293
+ if (tokensLength >= 3 &&
294
+ (token0Text == 'load' || token1Text == 'load'))
295
+ return loadHandler(item);
296
+ if (tokensLength >= 3 &&
297
+ token0Text in MATHOPS)
298
+ return mathopsHandler(item);
299
+ if (tokensLength >= 3 && token0Text == 'bitcast')
300
+ return bitcastHandler(item);
301
+ if (tokensLength >= 3 && token0Text == 'getelementptr')
302
+ return GEPHandler(item);
303
+ if (tokensLength >= 2 && token0Text == 'alloca')
304
+ return allocaHandler(item);
305
+ if (tokensLength >= 3 && token0Text == 'extractvalue')
306
+ return extractValueHandler(item);
307
+ if (tokensLength >= 3 && token0Text == 'insertvalue')
308
+ return insertValueHandler(item);
309
+ if (tokensLength >= 3 && token0Text == 'phi')
310
+ return phiHandler(item);
311
+ if (tokensLength >= 3 && token0Text == 'va_arg')
312
+ return va_argHandler(item);
313
+ if (tokensLength >= 3 && token0Text == 'landingpad')
314
+ return landingpadHandler(item);
315
+ if (token0Text === 'insertelement')
316
+ return insertElementHandler(item);
317
+ if (token0Text === 'extractelement')
318
+ return extractElementHandler(item);
319
+ if (token0Text === 'shufflevector')
320
+ return shuffleVectorHandler(item);
321
+ if (token0Text == 'fence')
322
+ return null;
323
+ } else if (item.indent === 0) {
324
+ if ((tokensLength >= 1 && token0Text.substr(-1) == ':') ||
325
+ (tokensLength >= 3 && token1Text == '<label>') ||
326
+ (tokensLength >= 2 && token1Text == ':'))
327
+ return labelHandler(item);
328
+ if (tokensLength >= 4 && token0Text == 'declare')
329
+ return externalHandler(item);
330
+ if (item.assignTo)
331
+ return globalHandler(item);
332
+ if (tokensLength >= 4 && token0Text == 'define' &&
333
+ item.tokens.slice(-1)[0].text == '{')
334
+ return funcHeaderHandler(item);
335
+ if (tokensLength >= 1 && token0Text == '}')
336
+ return funcEndHandler(item);
337
+ if (token0Text == 'module' && token1Text == 'asm') {
338
+ warn('Ignoring module asm: ' + item.tokens[2].text);
339
+ return null;
377
340
  }
378
- var eq;
379
- if (item.indent == 2 && (eq = findTokenText(item, '=')) >= 0) {
380
- item.assignTo = toNiceIdent(combineTokens(item.tokens.slice(0, eq)).text);
381
- item.tokens = item.tokens.slice(eq+1);
341
+ if (token0Text == 'attributes')
342
+ return null;
343
+ }
344
+ if (tokensLength >= 3 && (token0Text == 'call' || token1Text == 'call'))
345
+ return callHandler(item);
346
+ if (token0Text == 'target') {
347
+ if (token1Text == 'triple') {
348
+ var triple = item.tokens[3].text;
349
+ triple = triple.substr(1, triple.length-2);
350
+ var expected = TARGET_LE32 ? 'le32-unknown-nacl' : 'i386-pc-linux-gnu';
351
+ if (triple !== expected) {
352
+ warn('using an unexpected LLVM triple: ' + [triple, ' !== ', expected] + ' (are you using emcc for everything and not clang?)');
353
+ }
382
354
  }
383
- this.forwardItem(item, triage());
355
+ return null;
384
356
  }
385
- });
357
+ if (token0Text == ';')
358
+ return null;
359
+ if (tokensLength >= 3 && token0Text == 'invoke')
360
+ return invokeHandler(item);
361
+ if (tokensLength >= 3 && token0Text == 'atomicrmw' || token0Text == 'cmpxchg')
362
+ return atomicHandler(item);
363
+ throw 'Invalid token, cannot triage: ' + dump(item);
364
+ }
386
365
 
387
366
  // Line parsers to intermediate form
388
367
 
389
368
  // globals: type or variable
390
- substrate.addActor('Global', {
391
- processItem: function _global(item) {
392
- function scanConst(value, type) {
393
- // Gets an array of constant items, separated by ',' tokens
394
- function handleSegments(tokens) {
395
- // Handle a single segment (after comma separation)
396
- function handleSegment(segment) {
397
- if (segment[1].text == 'null') {
398
- return { intertype: 'value', ident: '0', type: 'i32' };
399
- } else if (segment[1].text == 'zeroinitializer') {
400
- Types.needAnalysis[segment[0].text] = 0;
401
- return { intertype: 'emptystruct', type: segment[0].text };
402
- } else if (segment[1].text in PARSABLE_LLVM_FUNCTIONS) {
403
- return parseLLVMFunctionCall(segment);
404
- } else if (segment[1].type && segment[1].type == '{') {
405
- Types.needAnalysis[segment[0].text] = 0;
406
- return { intertype: 'struct', type: segment[0].text, contents: handleSegments(segment[1].tokens) };
407
- } else if (segment[1].type && segment[1].type == '<') {
408
- Types.needAnalysis[segment[0].text] = 0;
409
- return { intertype: 'struct', type: segment[0].text, contents: handleSegments(segment[1].item.tokens[0].tokens) };
410
- } else if (segment[1].type && segment[1].type == '[') {
411
- Types.needAnalysis[segment[0].text] = 0;
412
- return { intertype: 'list', type: segment[0].text, contents: handleSegments(segment[1].item.tokens) };
413
- } else if (segment.length == 2) {
414
- Types.needAnalysis[segment[0].text] = 0;
415
- return { intertype: 'value', type: segment[0].text, ident: toNiceIdent(segment[1].text) };
416
- } else if (segment[1].text === 'c') {
417
- // string
418
- var text = segment[2].text;
419
- text = text.substr(1, text.length-2);
420
- return { intertype: 'string', text: text, type: 'i8*' };
421
- } else if (segment[1].text === 'blockaddress') {
422
- return parseBlockAddress(segment);
423
- } else {
424
- throw 'Invalid segment: ' + dump(segment);
425
- }
426
- };
427
- return splitTokenList(tokens).map(handleSegment);
428
- }
369
+ function noteGlobalVariable(ret) {
370
+ if (!NAMED_GLOBALS) {
371
+ Variables.globals[ret.ident].type = ret.type;
372
+ Variables.globals[ret.ident].external = ret.external;
373
+ }
374
+ Types.needAnalysis[ret.type] = 0;
375
+ }
429
376
 
430
- Types.needAnalysis[type] = 0;
431
- if (Runtime.isNumberType(type) || pointingLevels(type) >= 1) {
432
- return { value: toNiceIdent(value.text), type: type };
433
- } else if (value.text in ZEROINIT_UNDEF) { // undef doesn't really need initting, but why not
434
- return { intertype: 'emptystruct', type: type };
435
- } else if (value.text && value.text[0] == '"') {
436
- return { intertype: 'string', text: value.text.substr(1, value.text.length-2) };
437
- } else {
438
- if (value.type == '<') { // <{ i8 }> etc.
439
- value = value.item.tokens;
440
- }
441
- var contents;
442
- if (value.item) {
443
- // list of items
444
- contents = value.item.tokens;
445
- } else if (value.type == '{') {
446
- // struct
447
- contents = value.tokens;
448
- } else if (value[0]) {
449
- contents = value[0];
377
+ function globalHandler(item) {
378
+ function scanConst(value, type) {
379
+ // Gets an array of constant items, separated by ',' tokens
380
+ function handleSegments(tokens) {
381
+ // Handle a single segment (after comma separation)
382
+ function handleSegment(segment) {
383
+ if (segment[1].text == 'null') {
384
+ return { intertype: 'value', ident: '0', type: 'i32' };
385
+ } else if (segment[1].text == 'zeroinitializer') {
386
+ Types.needAnalysis[segment[0].text] = 0;
387
+ return { intertype: 'emptystruct', type: segment[0].text };
388
+ } else if (segment[1].text in PARSABLE_LLVM_FUNCTIONS) {
389
+ return parseLLVMFunctionCall(segment);
390
+ } else if (segment[1].type && segment[1].type == '{') {
391
+ Types.needAnalysis[segment[0].text] = 0;
392
+ return { intertype: 'struct', type: segment[0].text, contents: handleSegments(segment[1].tokens) };
393
+ } else if (segment[1].type && segment[1].type == '<') {
394
+ Types.needAnalysis[segment[0].text] = 0;
395
+ return { intertype: 'struct', type: segment[0].text, contents: handleSegments(segment[1].tokens[0].tokens) };
396
+ } else if (segment[1].type && segment[1].type == '[') {
397
+ Types.needAnalysis[segment[0].text] = 0;
398
+ return { intertype: 'list', type: segment[0].text, contents: handleSegments(segment[1].tokens) };
399
+ } else if (segment.length == 2) {
400
+ Types.needAnalysis[segment[0].text] = 0;
401
+ return { intertype: 'value', type: segment[0].text, ident: toNiceIdent(segment[1].text) };
402
+ } else if (segment[1].text === 'c') {
403
+ // string
404
+ var text = segment[2].text;
405
+ text = text.substr(1, text.length-2);
406
+ return { intertype: 'string', text: text, type: 'i8*' };
407
+ } else if (segment[1].text === 'blockaddress') {
408
+ return parseBlockAddress(segment);
450
409
  } else {
451
- throw '// interfailzzzzzzzzzzzzzz ' + dump(value.item) + ' ::: ' + dump(value);
410
+ throw 'Invalid segment: ' + dump(segment);
452
411
  }
453
- return { intertype: 'segments', contents: handleSegments(contents) };
454
- }
412
+ };
413
+ return splitTokenList(tokens).map(handleSegment);
455
414
  }
456
415
 
457
- cleanOutTokens(LLVM.VISIBILITIES, item.tokens, 2);
458
- if (item.tokens[2].text == 'alias') {
459
- cleanOutTokens(LLVM.LINKAGES, item.tokens, 3);
460
- cleanOutTokens(LLVM.VISIBILITIES, item.tokens, 3);
461
- var last = getTokenIndexByText(item.tokens, ';');
462
- var ret = {
463
- intertype: 'alias',
464
- ident: toNiceIdent(item.tokens[0].text),
465
- value: parseLLVMSegment(item.tokens.slice(3, last)),
466
- lineNum: item.lineNum
467
- };
468
- ret.type = ret.value.type;
469
- Types.needAnalysis[ret.type] = 0;
470
- if (!NAMED_GLOBALS) {
471
- Variables.globals[ret.ident].type = ret.type;
416
+ Types.needAnalysis[type] = 0;
417
+ if (Runtime.isNumberType(type) || pointingLevels(type) >= 1) {
418
+ return { value: toNiceIdent(value.text), type: type };
419
+ } else if (value.text in ZEROINIT_UNDEF) { // undef doesn't really need initting, but why not
420
+ return { intertype: 'emptystruct', type: type };
421
+ } else if (value.text && value.text[0] == '"') {
422
+ return { intertype: 'string', text: value.text.substr(1, value.text.length-2) };
423
+ } else {
424
+ if (value.type == '<') { // <{ i8 }> etc.
425
+ value = value.tokens;
426
+ }
427
+ var contents;
428
+ if (value.type && value.type !== '{') {
429
+ // list of items
430
+ contents = value.tokens;
431
+ } else if (value.type == '{') {
432
+ // struct
433
+ contents = value.tokens;
434
+ } else if (value[0]) {
435
+ contents = value[0];
436
+ } else {
437
+ throw '// interfailzzzzzzzzzzzzzz ' + dump(value);
472
438
  }
473
- return [ret];
439
+ return { intertype: 'segments', contents: handleSegments(contents) };
474
440
  }
475
- if (item.tokens[2].text == 'type') {
476
- var fields = [];
477
- var packed = false;
478
- if (Runtime.isNumberType(item.tokens[3].text)) {
479
- // Clang sometimes has |= i32| instead of |= { i32 }|
480
- fields = [item.tokens[3].text];
481
- } else if (item.tokens[3].text != 'opaque') {
482
- if (item.tokens[3].type == '<') {
483
- packed = true;
484
- item.tokens[3] = item.tokens[3].item.tokens[0];
485
- }
486
- var subTokens = item.tokens[3].tokens;
487
- if (subTokens) {
488
- subTokens.push({text:','});
489
- while (subTokens[0]) {
490
- var stop = 1;
491
- while ([','].indexOf(subTokens[stop].text) == -1) stop ++;
492
- fields.push(combineTokens(subTokens.slice(0, stop)).text);
493
- subTokens.splice(0, stop+1);
494
- }
495
- }
441
+ }
442
+
443
+ cleanOutTokens(LLVM.VISIBILITIES, item.tokens, 0);
444
+ if (item.tokens[0].text == 'alias') {
445
+ cleanOutTokens(LLVM.LINKAGES, item.tokens, 1);
446
+ cleanOutTokens(LLVM.VISIBILITIES, item.tokens, 1);
447
+ var last = getTokenIndexByText(item.tokens, ';');
448
+ var ret = {
449
+ intertype: 'alias',
450
+ ident: item.assignTo,
451
+ value: parseLLVMSegment(item.tokens.slice(1, last)),
452
+ lineNum: item.lineNum
453
+ };
454
+ ret.type = ret.value.type;
455
+ Types.needAnalysis[ret.type] = 0;
456
+ if (!NAMED_GLOBALS) {
457
+ Variables.globals[ret.ident].type = ret.type;
458
+ }
459
+ return ret;
460
+ }
461
+ if (item.tokens[0].text == 'type') {
462
+ var fields = [];
463
+ var packed = false;
464
+ if (Runtime.isNumberType(item.tokens[1].text)) {
465
+ // Clang sometimes has |= i32| instead of |= { i32 }|
466
+ fields = [item.tokens[1].text];
467
+ } else if (item.tokens[1].text != 'opaque') {
468
+ if (item.tokens[1].type == '<') {
469
+ packed = true;
470
+ item.tokens[1] = item.tokens[1].tokens[0];
496
471
  }
497
- return [{
498
- intertype: 'type',
499
- name_: item.tokens[0].text,
500
- fields: fields,
501
- packed: packed,
502
- lineNum: item.lineNum
503
- }];
504
- } else {
505
- // variable
506
- var ident = item.tokens[0].text;
507
- var private_ = findTokenText(item, 'private') >= 0 || findTokenText(item, 'internal') >= 0;
508
- var named = findTokenText(item, 'unnamed_addr') < 0;
509
- cleanOutTokens(LLVM.GLOBAL_MODIFIERS, item.tokens, [2, 3]);
510
- var external = false;
511
- if (item.tokens[2].text === 'external') {
512
- external = true;
513
- item.tokens.splice(2, 1);
472
+ var subTokens = item.tokens[1].tokens;
473
+ if (subTokens) {
474
+ subTokens.push({text:','});
475
+ while (subTokens[0]) {
476
+ var stop = 1;
477
+ while ([','].indexOf(subTokens[stop].text) == -1) stop ++;
478
+ fields.push(combineTokens(subTokens.slice(0, stop)).text);
479
+ subTokens.splice(0, stop+1);
480
+ }
514
481
  }
515
- Types.needAnalysis[item.tokens[2].text] = 0;
516
- var ret = {
517
- intertype: 'globalVariable',
518
- ident: toNiceIdent(ident),
519
- type: item.tokens[2].text,
520
- external: external,
521
- private_: private_,
522
- named: named,
523
- lineNum: item.lineNum
524
- };
525
- if (!NAMED_GLOBALS) {
526
- Variables.globals[ret.ident].type = ret.type;
527
- Variables.globals[ret.ident].external = external;
482
+ }
483
+ return {
484
+ intertype: 'type',
485
+ name_: item.assignTo,
486
+ fields: fields,
487
+ packed: packed,
488
+ lineNum: item.lineNum
489
+ };
490
+ } else {
491
+ // variable
492
+ var ident = item.assignTo;
493
+ var private_ = findTokenText(item, 'private') >= 0 || findTokenText(item, 'internal') >= 0;
494
+ var named = findTokenText(item, 'unnamed_addr') < 0;
495
+ cleanOutTokens(LLVM.GLOBAL_MODIFIERS, item.tokens, [0, 1]);
496
+ var external = false;
497
+ if (item.tokens[0].text === 'external') {
498
+ external = true;
499
+ item.tokens.splice(0, 1);
500
+ }
501
+ var ret = {
502
+ intertype: 'globalVariable',
503
+ ident: ident,
504
+ type: item.tokens[0].text,
505
+ external: external,
506
+ private_: private_,
507
+ named: named,
508
+ lineNum: item.lineNum
509
+ };
510
+ noteGlobalVariable(ret);
511
+ if (ident == '_llvm_global_ctors') {
512
+ ret.ctors = [];
513
+ var subTokens = item.tokens[1].tokens;
514
+ if (subTokens) {
515
+ splitTokenList(subTokens).forEach(function(segment) {
516
+ var parsed = parseLLVMSegment(segment);
517
+ assert(parsed.intertype === 'structvalue');
518
+ var ctor = toNiceIdent(parsed.params[1].ident);
519
+ ret.ctors.push(ctor);
520
+ if (ASM_JS) { // must export the global constructors from asm.js module, so mark as implemented and exported
521
+ Functions.implementedFunctions[ctor] = 'v';
522
+ EXPORTED_FUNCTIONS[ctor] = 1;
523
+ }
524
+ });
528
525
  }
529
- Types.needAnalysis[ret.type] = 0;
530
- if (ident == '@llvm.global_ctors') {
531
- ret.ctors = [];
532
- if (item.tokens[3].item) {
533
- var subTokens = item.tokens[3].item.tokens;
534
- splitTokenList(subTokens).forEach(function(segment) {
535
- var ctor = toNiceIdent(segment[1].tokens.slice(-1)[0].text);
536
- ret.ctors.push(ctor);
537
- if (ASM_JS) { // must export the global constructors from asm.js module, so mark as implemented and exported
538
- Functions.implementedFunctions[ctor] = 'v';
539
- EXPORTED_FUNCTIONS[ctor] = 1;
540
- }
541
- });
526
+ } else if (!external) {
527
+ if (item.tokens[1] && item.tokens[1].text != ';') {
528
+ if (item.tokens[1].text == 'c') {
529
+ item.tokens.splice(1, 1);
542
530
  }
543
- } else if (!external) {
544
- if (item.tokens[3] && item.tokens[3].text != ';') {
545
- if (item.tokens[3].text == 'c') {
546
- item.tokens.splice(3, 1);
547
- }
548
- if (item.tokens[3].text in PARSABLE_LLVM_FUNCTIONS) {
549
- ret.value = parseLLVMFunctionCall(item.tokens.slice(2));
550
- } else {
551
- ret.value = scanConst(item.tokens[3], ret.type);
552
- }
531
+ if (item.tokens[1].text in PARSABLE_LLVM_FUNCTIONS) {
532
+ ret.value = parseLLVMFunctionCall(item.tokens);
553
533
  } else {
554
- ret.value = { intertype: 'value', ident: '0', value: '0', type: ret.type };
534
+ ret.value = scanConst(item.tokens[1], ret.type);
555
535
  }
536
+ } else {
537
+ ret.value = { intertype: 'value', ident: '0', value: '0', type: ret.type };
556
538
  }
557
- return [ret];
558
539
  }
540
+ return ret;
559
541
  }
560
- });
542
+ }
561
543
  // function header
562
- var funcHeader = substrate.addActor('FuncHeader', {
563
- processItem: function(item) {
564
- item.tokens = item.tokens.filter(function(token) {
565
- return !(token.text in LLVM.LINKAGES || token.text in LLVM.PARAM_ATTR || token.text in LLVM.FUNC_ATTR || token.text in LLVM.CALLING_CONVENTIONS);
566
- });
567
- var params = parseParamTokens(item.tokens[2].item.tokens);
568
- if (sidePass) dprint('unparsedFunctions', 'Processing function: ' + item.tokens[1].text);
569
- return [{
570
- intertype: 'function',
571
- ident: toNiceIdent(item.tokens[1].text),
572
- returnType: item.tokens[0].text,
573
- params: params,
574
- hasVarArgs: hasVarArgs(params),
575
- lineNum: item.lineNum,
576
- }];
577
- }
578
- });
544
+ function funcHeaderHandler(item) {
545
+ item.tokens = item.tokens.filter(function(token) {
546
+ return !(token.text in LLVM.LINKAGES || token.text in LLVM.PARAM_ATTR || token.text in LLVM.FUNC_ATTR || token.text in LLVM.CALLING_CONVENTIONS);
547
+ });
548
+ var params = parseParamTokens(item.tokens[2].tokens);
549
+ if (sidePass) dprint('unparsedFunctions', 'Processing function: ' + item.tokens[1].text);
550
+ return {
551
+ intertype: 'function',
552
+ ident: toNiceIdent(item.tokens[1].text),
553
+ returnType: item.tokens[0].text,
554
+ params: params,
555
+ hasVarArgs: hasVarArgs(params),
556
+ lineNum: item.lineNum,
557
+ };
558
+ }
579
559
  // label
580
- substrate.addActor('Label', {
581
- processItem: function(item) {
582
- var rawLabel = item.tokens[0].text.substr(-1) == ':' ?
583
- '%' + item.tokens[0].text.substr(0, item.tokens[0].text.length-1) :
584
- (item.tokens[1].text == '<label>' ?
585
- '%' + item.tokens[2].text.substr(1) :
586
- '%' + item.tokens[0].text)
587
- var niceLabel = toNiceIdent(rawLabel);
588
- return [{
589
- intertype: 'label',
590
- ident: niceLabel,
591
- lineNum: item.lineNum
592
- }];
593
- }
594
- });
595
-
596
- // TODO: remove dis
597
- substrate.addActor('Reintegrator', {
598
- processItem: function(item) {
599
- this.forwardItem(item, '/dev/stdout');
600
- }
601
- });
560
+ function labelHandler(item) {
561
+ var rawLabel = item.tokens[0].text.substr(-1) == ':' ?
562
+ '%' + item.tokens[0].text.substr(0, item.tokens[0].text.length-1) :
563
+ (item.tokens[1].text == '<label>' ?
564
+ '%' + item.tokens[2].text.substr(1) :
565
+ '%' + item.tokens[0].text)
566
+ var niceLabel = toNiceIdent(rawLabel);
567
+ return {
568
+ intertype: 'label',
569
+ ident: niceLabel,
570
+ lineNum: item.lineNum
571
+ };
572
+ }
602
573
 
603
574
  // 'load'
604
- substrate.addActor('Load', {
605
- processItem: function(item) {
606
- item.intertype = 'load';
607
- cleanOutTokens(LLVM.ACCESS_OPTIONS, item.tokens, [0, 1]);
608
- item.pointerType = item.tokens[1].text;
609
- item.valueType = item.type = removePointing(item.pointerType);
610
- Types.needAnalysis[item.type] = 0;
611
- var last = getTokenIndexByText(item.tokens, ';');
612
- var segments = splitTokenList(item.tokens.slice(1, last));
613
- item.pointer = parseLLVMSegment(segments[0]);
614
- if (segments.length > 1) {
615
- assert(segments[1][0].text == 'align');
616
- item.align = parseInt(segments[1][1].text) || QUANTUM_SIZE; // 0 means preferred arch align
617
- } else {
618
- item.align = QUANTUM_SIZE;
619
- }
620
- item.ident = item.pointer.ident || null;
621
- this.forwardItem(item, 'Reintegrator');
575
+ function loadHandler(item) {
576
+ item.intertype = 'load';
577
+ cleanOutTokens(LLVM.ACCESS_OPTIONS, item.tokens, [0, 1]);
578
+ item.pointerType = item.tokens[1].text;
579
+ item.valueType = item.type = removePointing(item.pointerType);
580
+ Types.needAnalysis[item.type] = 0;
581
+ var last = getTokenIndexByText(item.tokens, ';');
582
+ var segments = splitTokenList(item.tokens.slice(1, last));
583
+ item.pointer = parseLLVMSegment(segments[0]);
584
+ if (segments.length > 1) {
585
+ assert(segments[1][0].text == 'align');
586
+ item.align = parseInt(segments[1][1].text) || QUANTUM_SIZE; // 0 means preferred arch align
587
+ } else {
588
+ item.align = QUANTUM_SIZE;
622
589
  }
623
- });
590
+ item.ident = item.pointer.ident || null;
591
+ return item;
592
+ }
624
593
  // 'extractvalue'
625
- substrate.addActor('ExtractValue', {
626
- processItem: function(item) {
627
- var last = getTokenIndexByText(item.tokens, ';');
628
- item.intertype = 'extractvalue';
629
- item.type = item.tokens[1].text; // Of the origin aggregate - not what we extract from it. For that, can only infer it later
630
- Types.needAnalysis[item.type] = 0;
631
- item.ident = toNiceIdent(item.tokens[2].text);
632
- item.indexes = splitTokenList(item.tokens.slice(4, last));
633
- this.forwardItem(item, 'Reintegrator');
634
- }
635
- });
594
+ function extractValueHandler(item) {
595
+ var last = getTokenIndexByText(item.tokens, ';');
596
+ item.intertype = 'extractvalue';
597
+ item.type = item.tokens[1].text; // Of the origin aggregate - not what we extract from it. For that, can only infer it later
598
+ Types.needAnalysis[item.type] = 0;
599
+ item.ident = toNiceIdent(item.tokens[2].text);
600
+ item.indexes = splitTokenList(item.tokens.slice(4, last));
601
+ return item;
602
+ }
636
603
  // 'insertvalue'
637
- substrate.addActor('InsertValue', {
638
- processItem: function(item) {
639
- var last = getTokenIndexByText(item.tokens, ';');
640
- item.intertype = 'insertvalue';
641
- item.type = item.tokens[1].text; // Of the origin aggregate, as well as the result
642
- Types.needAnalysis[item.type] = 0;
643
- item.ident = toNiceIdent(item.tokens[2].text);
644
- var segments = splitTokenList(item.tokens.slice(4, last));
645
- item.value = parseLLVMSegment(segments[0]);
646
- item.indexes = segments.slice(1);
647
- this.forwardItem(item, 'Reintegrator');
648
- }
649
- });
604
+ function insertValueHandler(item) {
605
+ var last = getTokenIndexByText(item.tokens, ';');
606
+ item.intertype = 'insertvalue';
607
+ item.type = item.tokens[1].text; // Of the origin aggregate, as well as the result
608
+ Types.needAnalysis[item.type] = 0;
609
+ item.ident = toNiceIdent(item.tokens[2].text);
610
+ var segments = splitTokenList(item.tokens.slice(4, last));
611
+ item.value = parseLLVMSegment(segments[0]);
612
+ item.indexes = segments.slice(1);
613
+ return item;
614
+ }
650
615
  // 'bitcast'
651
- substrate.addActor('Bitcast', {
652
- processItem: function(item) {
653
- item.intertype = 'bitcast';
654
- item.type = item.tokens[4].text; // The final type
655
- Types.needAnalysis[item.type] = 0;
656
- var to = getTokenIndexByText(item.tokens, 'to');
657
- item.params = [parseLLVMSegment(item.tokens.slice(1, to))];
658
- item.ident = item.params[0].ident;
659
- item.type2 = item.tokens[1].text; // The original type
660
- Types.needAnalysis[item.type2] = 0;
661
- this.forwardItem(item, 'Reintegrator');
662
- }
663
- });
616
+ function bitcastHandler(item) {
617
+ item.intertype = 'bitcast';
618
+ item.type = item.tokens[4].text; // The final type
619
+ Types.needAnalysis[item.type] = 0;
620
+ var to = getTokenIndexByText(item.tokens, 'to');
621
+ item.params = [parseLLVMSegment(item.tokens.slice(1, to))];
622
+ item.ident = item.params[0].ident;
623
+ item.type2 = item.tokens[1].text; // The original type
624
+ Types.needAnalysis[item.type2] = 0;
625
+ return item;
626
+ }
664
627
  // 'getelementptr'
665
- substrate.addActor('GEP', {
666
- processItem: function(item) {
667
- var first = 0;
668
- while (!isType(item.tokens[first].text)) first++;
669
- Types.needAnalysis[item.tokens[first].text] = 0;
670
- var last = getTokenIndexByText(item.tokens, ';');
671
- var segment = [ item.tokens[first], { text: 'getelementptr' }, null, { item: {
672
- tokens: item.tokens.slice(first, last)
673
- } } ];
674
- var data = parseLLVMFunctionCall(segment);
675
- item.intertype = 'getelementptr';
676
- item.type = '*'; // We need type info to determine this - all we know is it's a pointer
677
- item.params = data.params;
678
- item.ident = data.ident;
679
- this.forwardItem(item, 'Reintegrator');
680
- }
681
- });
628
+ function GEPHandler(item) {
629
+ var first = 0;
630
+ while (!isType(item.tokens[first].text)) first++;
631
+ Types.needAnalysis[item.tokens[first].text] = 0;
632
+ var last = getTokenIndexByText(item.tokens, ';');
633
+ var segment = [ item.tokens[first], { text: 'getelementptr' }, null, {
634
+ tokens: item.tokens.slice(first, last)
635
+ } ];
636
+ var data = parseLLVMFunctionCall(segment);
637
+ item.intertype = 'getelementptr';
638
+ item.type = '*'; // We need type info to determine this - all we know is it's a pointer
639
+ item.params = data.params;
640
+ item.ident = data.ident;
641
+ return item;
642
+ }
682
643
  // 'call', 'invoke'
683
644
  function makeCall(item, type) {
684
645
  item.intertype = type;
@@ -698,17 +659,27 @@ function intertyper(data, sidePass, baseLineNums) {
698
659
  var tokensLeft = item.tokens.slice(2);
699
660
  item.ident = eatLLVMIdent(tokensLeft);
700
661
  if (item.ident == 'asm') {
662
+ if (ASM_JS) {
663
+ Types.hasInlineJS = true;
664
+ warnOnce('inline JavaScript (asm, EM_ASM) will cause the code to no longer fall in the asm.js subset of JavaScript, which can reduce performance - consider using emscripten_run_script');
665
+ }
666
+ assert(TARGET_LE32, 'inline js is only supported in le32');
701
667
  // Inline assembly is just JavaScript that we paste into the code
702
668
  item.intertype = 'value';
703
669
  if (tokensLeft[0].text == 'sideeffect') tokensLeft.splice(0, 1);
704
670
  item.ident = tokensLeft[0].text.substr(1, tokensLeft[0].text.length-2) || ';'; // use ; for empty inline assembly
671
+ assert((item.tokens[5].text.match(/=/g) || []).length <= 1, 'we only support at most 1 exported variable from inline js: ' + item.ident);
705
672
  var i = 0;
706
- splitTokenList(tokensLeft[3].item.tokens).map(function(element) {
673
+ var params = [], args = [];
674
+ splitTokenList(tokensLeft[3].tokens).map(function(element) {
707
675
  var ident = toNiceIdent(element[1].text);
708
676
  var type = element[0].text;
709
- item.ident = item.ident.replace(new RegExp('\\$' + i++, 'g'), ident);
677
+ params.push('$' + (i++));
678
+ args.push(ident);
710
679
  });
711
- return { forward: null, ret: [item], item: item };
680
+ if (item.assignTo) item.ident = 'return ' + item.ident;
681
+ item.ident = '(function(' + params + ') { ' + item.ident + ' })(' + args + ');';
682
+ return { forward: null, ret: item, item: item };
712
683
  }
713
684
  if (item.ident.substr(-2) == '()') {
714
685
  // See comment in isStructType()
@@ -719,7 +690,7 @@ function intertyper(data, sidePass, baseLineNums) {
719
690
  }
720
691
  item.params = [];
721
692
  } else {
722
- item.params = parseParamTokens(tokensLeft[0].item.tokens);
693
+ item.params = parseParamTokens(tokensLeft[0].tokens);
723
694
  }
724
695
  item.ident = toNiceIdent(item.ident);
725
696
  if (type === 'invoke') {
@@ -731,330 +702,498 @@ function intertyper(data, sidePass, baseLineNums) {
731
702
  if (item.indent == 2) {
732
703
  // standalone call - not in assign
733
704
  item.standalone = true;
734
- return { forward: null, ret: [item], item: item };
705
+ return { forward: null, ret: item, item: item };
735
706
  }
736
- return { forward: item, ret: [], item: item };
707
+ return { forward: item, ret: null, item: item };
737
708
  }
738
- substrate.addActor('Call', {
739
- processItem: function(item) {
740
- var result = makeCall.call(this, item, 'call');
741
- if (result.forward) this.forwardItem(result.forward, 'Reintegrator');
742
- return result.ret;
743
- }
744
- });
745
- substrate.addActor('Invoke', {
746
- processItem: function(item) {
747
- var result = makeCall.call(this, item, 'invoke');
748
- if (DISABLE_EXCEPTION_CATCHING == 1) {
749
- result.item.intertype = 'call';
750
- result.ret.push({
751
- intertype: 'branch',
752
- label: result.item.toLabel,
753
- lineNum: (result.forward ? item.parentLineNum : item.lineNum) + 0.5
754
- });
755
- }
756
- if (result.forward) this.forwardItem(result.forward, 'Reintegrator');
757
- return result.ret;
709
+ function callHandler(item) {
710
+ var result = makeCall.call(this, item, 'call');
711
+ if (result.forward) this.forwardItem(result.forward, 'Reintegrator');
712
+ return result.ret;
713
+ }
714
+ function invokeHandler(item) {
715
+ var result = makeCall.call(this, item, 'invoke');
716
+ if (DISABLE_EXCEPTION_CATCHING == 1) {
717
+ result.item.intertype = 'call';
718
+ finalResults.push({
719
+ intertype: 'branch',
720
+ label: result.item.toLabel,
721
+ lineNum: (result.forward ? item.parentLineNum : item.lineNum) + 0.5
722
+ });
758
723
  }
759
- });
760
- substrate.addActor('Atomic', {
761
- processItem: function(item) {
762
- item.intertype = 'atomic';
763
- if (item.tokens[0].text == 'atomicrmw') {
764
- if (item.tokens[1].text == 'volatile') item.tokens.splice(1, 1);
765
- item.op = item.tokens[1].text;
766
- item.tokens.splice(1, 1);
767
- } else {
768
- assert(item.tokens[0].text == 'cmpxchg')
769
- if (item.tokens[1].text == 'volatile') item.tokens.splice(1, 1);
770
- item.op = 'cmpxchg';
771
- }
772
- var last = getTokenIndexByText(item.tokens, ';');
773
- item.params = splitTokenList(item.tokens.slice(1, last)).map(parseLLVMSegment);
774
- item.type = item.params[1].type;
775
- this.forwardItem(item, 'Reintegrator');
724
+ if (result.forward) this.forwardItem(result.forward, 'Reintegrator');
725
+ return result.ret;
726
+ }
727
+ function atomicHandler(item) {
728
+ item.intertype = 'atomic';
729
+ if (item.tokens[0].text == 'atomicrmw') {
730
+ if (item.tokens[1].text == 'volatile') item.tokens.splice(1, 1);
731
+ item.op = item.tokens[1].text;
732
+ item.tokens.splice(1, 1);
733
+ } else {
734
+ assert(item.tokens[0].text == 'cmpxchg')
735
+ if (item.tokens[1].text == 'volatile') item.tokens.splice(1, 1);
736
+ item.op = 'cmpxchg';
776
737
  }
777
- });
738
+ var last = getTokenIndexByText(item.tokens, ';');
739
+ item.params = splitTokenList(item.tokens.slice(1, last)).map(parseLLVMSegment);
740
+ item.type = item.params[1].type;
741
+ return item;
742
+ }
778
743
  // 'landingpad'
779
- substrate.addActor('Landingpad', {
780
- processItem: function(item) {
781
- item.intertype = 'landingpad';
782
- item.type = item.tokens[1].text;
783
- item.catchables = [];
784
- var catchIdx = findTokenText(item, "catch");
785
- if (catchIdx != -1) {
786
- do {
787
- var nextCatchIdx = findTokenTextAfter(item, "catch", catchIdx+1);
788
- if (nextCatchIdx == -1)
789
- nextCatchIdx = item.tokens.length;
790
- item.catchables.push(parseLLVMSegment(item.tokens.slice(catchIdx+2, nextCatchIdx)));
791
- catchIdx = nextCatchIdx;
792
- } while (catchIdx != item.tokens.length);
793
- }
794
- Types.needAnalysis[item.type] = 0;
795
- this.forwardItem(item, 'Reintegrator');
744
+ function landingpadHandler(item) {
745
+ item.intertype = 'landingpad';
746
+ item.type = item.tokens[1].text;
747
+ item.catchables = [];
748
+ var catchIdx = findTokenText(item, "catch");
749
+ if (catchIdx != -1) {
750
+ do {
751
+ var nextCatchIdx = findTokenTextAfter(item, "catch", catchIdx+1);
752
+ if (nextCatchIdx == -1)
753
+ nextCatchIdx = item.tokens.length;
754
+ item.catchables.push(parseLLVMSegment(item.tokens.slice(catchIdx+2, nextCatchIdx)));
755
+ catchIdx = nextCatchIdx;
756
+ } while (catchIdx != item.tokens.length);
796
757
  }
797
- });
758
+ Types.needAnalysis[item.type] = 0;
759
+ return item;
760
+ }
761
+ function insertElementHandler(item) {
762
+ var last = getTokenIndexByText(item.tokens, ';');
763
+ item.intertype = 'insertelement';
764
+ item.type = item.tokens[1].text;
765
+ item.ident = toNiceIdent(item.tokens[2].text);
766
+ var segments = splitTokenList(item.tokens.slice(4, last));
767
+ item.value = parseLLVMSegment(segments[0]);
768
+ item.index = parseLLVMSegment(segments[1]);
769
+ return item;
770
+ }
771
+ function extractElementHandler(item) {
772
+ var last = getTokenIndexByText(item.tokens, ';');
773
+ item.intertype = 'extracttelement';
774
+ item.type = item.tokens[1].text;
775
+ item.ident = toNiceIdent(item.tokens[2].text);
776
+ item.value = parseLLVMSegment(item.tokens.slice(4));
777
+ return item;
778
+ }
779
+ function shuffleVectorHandler(item) {
780
+ var last = getTokenIndexByText(item.tokens, ';');
781
+ item.intertype = 'shufflevector';
782
+ item.type = item.tokens[1].text; // Of the origin aggregate, as well as the result
783
+ Types.needAnalysis[item.type] = 0;
784
+ item.ident = toNiceIdent(item.tokens[2].text);
785
+ var segments = splitTokenList(item.tokens.slice(4, last));
786
+ item.value = parseLLVMSegment(segments[0]);
787
+ item.mask = parseLLVMSegment(segments[1]);
788
+ return item;
789
+ }
798
790
  // 'alloca'
799
- var allocaPossibleVars = ['allocatedNum'];
800
- substrate.addActor('Alloca', {
801
- processItem: function(item) {
802
- item.intertype = 'alloca';
803
- item.allocatedType = item.tokens[1].text;
804
- if (item.tokens.length > 3 && Runtime.isNumberType(item.tokens[3].text)) {
805
- item.allocatedNum = toNiceIdent(item.tokens[4].text);
806
- item.possibleVars = allocaPossibleVars;
807
- } else {
808
- item.allocatedNum = 1;
809
- }
810
- item.type = addPointing(item.tokens[1].text); // type of pointer we will get
811
- Types.needAnalysis[item.type] = 0;
812
- item.type2 = item.tokens[1].text; // value we will create, and get a pointer to
813
- Types.needAnalysis[item.type2] = 0;
814
- this.forwardItem(item, 'Reintegrator');
791
+ function allocaHandler(item) {
792
+ item.intertype = 'alloca';
793
+ item.allocatedType = item.tokens[1].text;
794
+ if (item.tokens.length > 3 && Runtime.isNumberType(item.tokens[3].text)) {
795
+ item.ident = toNiceIdent(item.tokens[4].text);
796
+ } else {
797
+ item.ident = 1;
815
798
  }
816
- });
799
+ item.type = addPointing(item.tokens[1].text); // type of pointer we will get
800
+ Types.needAnalysis[item.type] = 0;
801
+ item.type2 = item.tokens[1].text; // value we will create, and get a pointer to
802
+ Types.needAnalysis[item.type2] = 0;
803
+ return item;
804
+ }
817
805
  // 'phi'
818
- substrate.addActor('Phi', {
819
- processItem: function(item) {
820
- item.intertype = 'phi';
821
- item.type = item.tokens[1].text;
822
- var typeToken = [item.tokens[1]];
823
- Types.needAnalysis[item.type] = 0;
824
- var last = getTokenIndexByText(item.tokens, ';');
825
- item.params = splitTokenList(item.tokens.slice(2, last)).map(function(segment) {
826
- var subSegments = splitTokenList(segment[0].item.tokens);
827
- var ret = {
828
- intertype: 'phiparam',
829
- label: toNiceIdent(subSegments[1][0].text),
830
- value: parseLLVMSegment(typeToken.concat(subSegments[0]))
831
- };
832
- return ret;
833
- }).filter(function(param) { return param.value && param.value.ident != 'undef' });
834
- this.forwardItem(item, 'Reintegrator');
835
- }
836
- });
806
+ function phiHandler(item) {
807
+ item.intertype = 'phi';
808
+ item.type = item.tokens[1].text;
809
+ var typeToken = [item.tokens[1]];
810
+ Types.needAnalysis[item.type] = 0;
811
+ var last = getTokenIndexByText(item.tokens, ';');
812
+ item.params = splitTokenList(item.tokens.slice(2, last)).map(function(segment) {
813
+ var subSegments = splitTokenList(segment[0].tokens);
814
+ var ret = {
815
+ intertype: 'phiparam',
816
+ label: toNiceIdent(subSegments[1][0].text),
817
+ value: parseLLVMSegment(typeToken.concat(subSegments[0]))
818
+ };
819
+ return ret;
820
+ }).filter(function(param) { return param.value && param.value.ident != 'undef' });
821
+ return item;
822
+ }
837
823
  // 'phi'
838
- substrate.addActor('va_arg', {
839
- processItem: function(item) {
840
- item.intertype = 'va_arg';
841
- var segments = splitTokenList(item.tokens.slice(1));
842
- item.type = segments[1][0].text;
843
- item.value = parseLLVMSegment(segments[0]);
844
- this.forwardItem(item, 'Reintegrator');
845
- }
846
- });
824
+ function va_argHandler(item) {
825
+ item.intertype = 'va_arg';
826
+ var segments = splitTokenList(item.tokens.slice(1));
827
+ item.type = segments[1][0].text;
828
+ item.value = parseLLVMSegment(segments[0]);
829
+ return item;
830
+ }
847
831
  // mathops
848
- substrate.addActor('Mathops', {
849
- processItem: function(item) {
850
- item.intertype = 'mathop';
851
- item.op = item.tokens[0].text;
852
- item.variant = null;
853
- while (item.tokens[1].text in NSW_NUW) item.tokens.splice(1, 1);
854
- if (['icmp', 'fcmp'].indexOf(item.op) != -1) {
855
- item.variant = item.tokens[1].text;
856
- item.tokens.splice(1, 1);
857
- }
858
- if (item.tokens[1].text == 'exact') item.tokens.splice(1, 1); // TODO: Implement trap values
859
- var segments = splitTokenList(item.tokens.slice(1));
860
- item.params = [];
861
- for (var i = 1; i <= 4; i++) {
862
- if (segments[i-1]) {
863
- if (i > 1 && segments[i-1].length == 1 && segments[0].length > 1 && !isType(segments[i-1][0].text)) {
864
- segments[i-1].unshift(segments[0][0]); // Add the type from the first segment, they are all alike
865
- }
866
- item.params[i-1] = parseLLVMSegment(segments[i-1]);
867
- }
868
- }
869
- var setParamTypes = true;
870
- if (item.op === 'select') {
871
- assert(item.params[1].type === item.params[2].type);
872
- item.type = item.params[1].type;
873
- } else if (item.op in LLVM.CONVERSIONS) {
874
- item.type = item.params[1].type;
875
- setParamTypes = false;
876
- } else {
877
- item.type = item.params[0].type;
878
- }
879
- if (setParamTypes) {
880
- for (var i = 0; i < 4; i++) {
881
- if (item.params[i]) item.params[i].type = item.type; // All params have the same type, normally
832
+ function mathopsHandler(item) {
833
+ item.intertype = 'mathop';
834
+ item.op = item.tokens[0].text;
835
+ item.variant = null;
836
+ while (item.tokens[1].text in NSW_NUW) item.tokens.splice(1, 1);
837
+ if (['icmp', 'fcmp'].indexOf(item.op) != -1) {
838
+ item.variant = item.tokens[1].text;
839
+ item.tokens.splice(1, 1);
840
+ }
841
+ if (item.tokens[1].text == 'exact') item.tokens.splice(1, 1); // TODO: Implement trap values
842
+ var segments = splitTokenList(item.tokens.slice(1));
843
+ item.params = [];
844
+ for (var i = 1; i <= 4; i++) {
845
+ if (segments[i-1]) {
846
+ if (i > 1 && segments[i-1].length == 1 && segments[0].length > 1 && !isType(segments[i-1][0].text)) {
847
+ segments[i-1].unshift(segments[0][0]); // Add the type from the first segment, they are all alike
882
848
  }
849
+ item.params[i-1] = parseLLVMSegment(segments[i-1]);
883
850
  }
884
- if (item.op in LLVM.EXTENDS) {
885
- item.type = item.params[1].ident;
886
- item.params[0].type = item.params[1].type;
887
- // TODO: also remove 2nd param?
888
- } else if (item.op in LLVM.COMPS) {
889
- item.type = 'i1';
851
+ }
852
+ var setParamTypes = true;
853
+ if (item.op === 'select') {
854
+ assert(item.params[1].type === item.params[2].type);
855
+ item.type = item.params[1].type;
856
+ } else if (item.op in LLVM.CONVERSIONS) {
857
+ item.type = item.params[1].type;
858
+ setParamTypes = false;
859
+ } else {
860
+ item.type = item.params[0].type;
861
+ }
862
+ if (setParamTypes) {
863
+ for (var i = 0; i < 4; i++) {
864
+ if (item.params[i]) item.params[i].type = item.type; // All params have the same type, normally
890
865
  }
891
- if (USE_TYPED_ARRAYS == 2) {
892
- // Some specific corrections, since 'i64' is special
893
- if (item.op in LLVM.SHIFTS) {
894
- item.params[1].type = 'i32';
895
- } else if (item.op == 'select') {
896
- item.params[0].type = 'i1';
897
- }
866
+ }
867
+ if (item.op in LLVM.EXTENDS) {
868
+ item.type = item.params[1].ident;
869
+ item.params[0].type = item.params[1].type;
870
+ // TODO: also remove 2nd param?
871
+ } else if (item.op in LLVM.COMPS) {
872
+ item.type = 'i1';
873
+ if (item.params[1].intertype === 'type') item.params[1].intertype = 'value'; // parsed as type, but comparisons have just values there
874
+ }
875
+ if (USE_TYPED_ARRAYS == 2) {
876
+ // Some specific corrections, since 'i64' is special
877
+ if (item.op in LLVM.SHIFTS) {
878
+ item.params[1].type = 'i32';
879
+ } else if (item.op == 'select') {
880
+ item.params[0].type = 'i1';
898
881
  }
899
- Types.needAnalysis[item.type] = 0;
900
- this.forwardItem(item, 'Reintegrator');
901
882
  }
902
- });
883
+ Types.needAnalysis[item.type] = 0;
884
+ return item;
885
+ }
903
886
  // 'store'
904
- substrate.addActor('Store', {
905
- processItem: function(item) {
906
- cleanOutTokens(LLVM.ACCESS_OPTIONS, item.tokens, [0, 1]);
907
- var segments = splitTokenList(item.tokens.slice(1));
908
- var ret = {
909
- intertype: 'store',
910
- valueType: item.tokens[1].text,
911
- value: parseLLVMSegment(segments[0]),
912
- pointer: parseLLVMSegment(segments[1]),
913
- lineNum: item.lineNum
914
- };
915
- Types.needAnalysis[ret.valueType] = 0;
916
- ret.ident = toNiceIdent(ret.pointer.ident);
917
- ret.pointerType = ret.pointer.type;
918
- Types.needAnalysis[ret.pointerType] = 0;
919
- if (segments.length > 2) {
920
- assert(segments[2][0].text == 'align');
921
- ret.align = parseInt(segments[2][1].text) || QUANTUM_SIZE; // 0 means preferred arch align
922
- } else {
923
- ret.align = QUANTUM_SIZE;
924
- }
925
- return [ret];
887
+ function storeHandler(item) {
888
+ cleanOutTokens(LLVM.ACCESS_OPTIONS, item.tokens, [0, 1]);
889
+ var segments = splitTokenList(item.tokens.slice(1));
890
+ var ret = {
891
+ intertype: 'store',
892
+ valueType: item.tokens[1].text,
893
+ value: parseLLVMSegment(segments[0]),
894
+ pointer: parseLLVMSegment(segments[1]),
895
+ lineNum: item.lineNum
896
+ };
897
+ Types.needAnalysis[ret.valueType] = 0;
898
+ ret.ident = toNiceIdent(ret.pointer.ident);
899
+ ret.pointerType = ret.pointer.type;
900
+ Types.needAnalysis[ret.pointerType] = 0;
901
+ if (segments.length > 2) {
902
+ assert(segments[2][0].text == 'align');
903
+ ret.align = parseInt(segments[2][1].text) || QUANTUM_SIZE; // 0 means preferred arch align
904
+ } else {
905
+ ret.align = QUANTUM_SIZE;
926
906
  }
927
- });
907
+ return ret;
908
+ }
928
909
  // 'br'
929
- substrate.addActor('Branch', {
930
- processItem: function(item) {
931
- if (item.tokens[1].text == 'label') {
932
- return [{
933
- intertype: 'branch',
934
- label: toNiceIdent(item.tokens[2].text),
935
- lineNum: item.lineNum
936
- }];
937
- } else {
938
- var commaIndex = findTokenText(item, ',');
939
- return [{
940
- intertype: 'branch',
941
- value: parseLLVMSegment(item.tokens.slice(1, commaIndex)),
942
- labelTrue: toNiceIdent(item.tokens[commaIndex+2].text),
943
- labelFalse: toNiceIdent(item.tokens[commaIndex+5].text),
944
- lineNum: item.lineNum
945
- }];
946
- }
947
- }
948
- });
949
- // 'ret'
950
- substrate.addActor('Return', {
951
- processItem: function(item) {
952
- var type = item.tokens[1].text;
953
- Types.needAnalysis[type] = 0;
954
- return [{
955
- intertype: 'return',
956
- type: type,
957
- value: (item.tokens[2] && type !== 'void') ? parseLLVMSegment(item.tokens.slice(1)) : null,
910
+ function branchHandler(item) {
911
+ if (item.tokens[1].text == 'label') {
912
+ return {
913
+ intertype: 'branch',
914
+ label: toNiceIdent(item.tokens[2].text),
958
915
  lineNum: item.lineNum
959
- }];
960
- }
961
- });
962
- // 'resume' - partial implementation
963
- substrate.addActor('Resume', {
964
- processItem: function(item) {
965
- return [{
966
- intertype: 'resume',
967
- ident: toNiceIdent(item.tokens[2].text),
916
+ };
917
+ } else {
918
+ var commaIndex = findTokenText(item, ',');
919
+ return {
920
+ intertype: 'branch',
921
+ value: parseLLVMSegment(item.tokens.slice(1, commaIndex)),
922
+ labelTrue: toNiceIdent(item.tokens[commaIndex+2].text),
923
+ labelFalse: toNiceIdent(item.tokens[commaIndex+5].text),
968
924
  lineNum: item.lineNum
969
- }];
925
+ };
970
926
  }
971
- });
927
+ }
928
+ // 'ret'
929
+ function returnHandler(item) {
930
+ var type = item.tokens[1].text;
931
+ Types.needAnalysis[type] = 0;
932
+ return {
933
+ intertype: 'return',
934
+ type: type,
935
+ value: (item.tokens[2] && type !== 'void') ? parseLLVMSegment(item.tokens.slice(1)) : null,
936
+ lineNum: item.lineNum
937
+ };
938
+ }
939
+ // 'resume' - partial implementation
940
+ function resumeHandler(item) {
941
+ return {
942
+ intertype: 'resume',
943
+ ident: toNiceIdent(item.tokens[2].text),
944
+ lineNum: item.lineNum
945
+ };
946
+ }
972
947
  // 'switch'
973
- substrate.addActor('Switch', {
974
- processItem: function(item) {
975
- function parseSwitchLabels(item) {
976
- var ret = [];
977
- var tokens = item.item.tokens;
978
- while (tokens.length > 0) {
979
- ret.push({
980
- value: tokens[1].text,
981
- label: toNiceIdent(tokens[4].text)
982
- });
983
- tokens = tokens.slice(5);
984
- }
985
- return ret;
948
+ function switchHandler(item) {
949
+ function parseSwitchLabels(item) {
950
+ var ret = [];
951
+ var tokens = item.tokens;
952
+ while (tokens.length > 0) {
953
+ ret.push({
954
+ value: tokens[1].text,
955
+ label: toNiceIdent(tokens[4].text)
956
+ });
957
+ tokens = tokens.slice(5);
986
958
  }
987
- var type = item.tokens[1].text;
988
- Types.needAnalysis[type] = 0;
989
- return [{
990
- intertype: 'switch',
991
- type: type,
992
- ident: toNiceIdent(item.tokens[2].text),
993
- defaultLabel: toNiceIdent(item.tokens[5].text),
994
- switchLabels: parseSwitchLabels(item.tokens[6]),
995
- lineNum: item.lineNum
996
- }];
959
+ return ret;
997
960
  }
998
- });
961
+ var type = item.tokens[1].text;
962
+ Types.needAnalysis[type] = 0;
963
+ return {
964
+ intertype: 'switch',
965
+ type: type,
966
+ ident: toNiceIdent(item.tokens[2].text),
967
+ defaultLabel: toNiceIdent(item.tokens[5].text),
968
+ switchLabels: parseSwitchLabels(item.tokens[6]),
969
+ lineNum: item.lineNum
970
+ };
971
+ }
999
972
  // function end
1000
- substrate.addActor('FuncEnd', {
1001
- processItem: function(item) {
1002
- return [{
1003
- intertype: 'functionEnd',
1004
- lineNum: item.lineNum
1005
- }];
1006
- }
1007
- });
973
+ function funcEndHandler(item) {
974
+ return {
975
+ intertype: 'functionEnd',
976
+ lineNum: item.lineNum
977
+ };
978
+ }
1008
979
  // external function stub
1009
- substrate.addActor('External', {
1010
- processItem: function(item) {
1011
- while (item.tokens[1].text in LLVM.LINKAGES || item.tokens[1].text in LLVM.PARAM_ATTR || item.tokens[1].text in LLVM.VISIBILITIES || item.tokens[1].text in LLVM.CALLING_CONVENTIONS) {
1012
- item.tokens.splice(1, 1);
1013
- }
1014
- var params = parseParamTokens(item.tokens[3].item.tokens);
1015
- return [{
1016
- intertype: 'functionStub',
1017
- ident: toNiceIdent(item.tokens[2].text),
1018
- returnType: item.tokens[1],
1019
- params: params,
1020
- hasVarArgs: hasVarArgs(params),
1021
- lineNum: item.lineNum
1022
- }];
980
+ function externalHandler(item) {
981
+ while (item.tokens[1].text in LLVM.LINKAGES || item.tokens[1].text in LLVM.PARAM_ATTR || item.tokens[1].text in LLVM.VISIBILITIES || item.tokens[1].text in LLVM.CALLING_CONVENTIONS) {
982
+ item.tokens.splice(1, 1);
1023
983
  }
1024
- });
984
+ var params = parseParamTokens(item.tokens[3].tokens);
985
+ return {
986
+ intertype: 'functionStub',
987
+ ident: toNiceIdent(item.tokens[2].text),
988
+ returnType: item.tokens[1],
989
+ params: params,
990
+ hasVarArgs: hasVarArgs(params),
991
+ lineNum: item.lineNum
992
+ };
993
+ }
1025
994
  // 'unreachable'
1026
- substrate.addActor('Unreachable', {
1027
- processItem: function(item) {
1028
- return [{
1029
- intertype: 'unreachable',
1030
- lineNum: item.lineNum
1031
- }];
1032
- }
1033
- });
995
+ function unreachableHandler(item) {
996
+ return {
997
+ intertype: 'unreachable',
998
+ lineNum: item.lineNum
999
+ };
1000
+ }
1034
1001
  // 'indirectbr'
1035
- substrate.addActor('IndirectBr', {
1036
- processItem: function(item) {
1037
- var ret = {
1038
- intertype: 'indirectbr',
1039
- value: parseLLVMSegment(splitTokenList(item.tokens.slice(1))[0]),
1040
- type: item.tokens[1].text,
1041
- lineNum: item.lineNum
1042
- };
1043
- Types.needAnalysis[ret.type] = 0;
1044
- return [ret];
1002
+ function indirectBrHandler(item) {
1003
+ var ret = {
1004
+ intertype: 'indirectbr',
1005
+ value: parseLLVMSegment(splitTokenList(item.tokens.slice(1))[0]),
1006
+ type: item.tokens[1].text,
1007
+ lineNum: item.lineNum
1008
+ };
1009
+ Types.needAnalysis[ret.type] = 0;
1010
+ return ret;
1011
+ }
1012
+
1013
+ // Fast paths - quick parses of common patterns, avoid tokenizing entirely
1014
+
1015
+ function tryFastPaths(line) {
1016
+ var m, ret;
1017
+ if (phase === 'pre') {
1018
+ // string constant
1019
+ if (0) { // works, but not worth it m = /([@\.\w\d_]+) = (private )?(unnamed_addr )?(constant )?(\[\d+ x i8\]) c"([^"]+)".*/.exec(line.lineText)) {
1020
+ if (m[1] === '@llvm.global_ctors') return ret;
1021
+ ret = {
1022
+ intertype: 'globalVariable',
1023
+ ident: toNiceIdent(m[1]),
1024
+ type: m[5],
1025
+ external: false,
1026
+ private_: m[2] !== null,
1027
+ named: m[3] === null,
1028
+ lineNum: line.lineNum,
1029
+ value: {
1030
+ intertype: 'string',
1031
+ text: m[6]
1032
+ }
1033
+ };
1034
+ noteGlobalVariable(ret);
1035
+ }
1036
+ } else if (phase === 'funcs') {
1037
+ // TODO: (void)call, store
1038
+ if (m = /^ (%[\w\d\._]+) = (getelementptr|load|icmp) ([%\w\d\._ ,\*\-@]+)$/.exec(line.lineText)) {
1039
+ var assignTo = m[1];
1040
+ var intertype = m[2];
1041
+ var args = m[3];
1042
+ switch (intertype) {
1043
+ case 'getelementptr': {
1044
+ if (args[0] === 'i' && args.indexOf('inbounds ') === 0) {
1045
+ args = args.substr(9);
1046
+ }
1047
+ var params = args.split(', ').map(function(param) {
1048
+ var parts = param.split(' ');
1049
+ assert(parts.length === 2);
1050
+ Types.needAnalysis[parts[0]] = 0;
1051
+ return {
1052
+ intertype: 'value',
1053
+ type: parts[0],
1054
+ ident: toNiceIdent(parts[1]),
1055
+ byVal: 0
1056
+ }
1057
+ });
1058
+ ret = {
1059
+ intertype: 'getelementptr',
1060
+ lineNum: line.lineNum,
1061
+ assignTo: toNiceIdent(assignTo),
1062
+ ident: params[0].ident,
1063
+ type: '*',
1064
+ params: params
1065
+ };
1066
+ break;
1067
+ }
1068
+ case 'load': {
1069
+ if (m = /(^[%\w\d\._\-@\*]+) ([%\w\d\._\-@]+)(, align \d+)?$/.exec(args)) {
1070
+ var ident = toNiceIdent(m[2]);
1071
+ var type = m[1];
1072
+ assert(type[type.length-1] === '*', type);
1073
+ var valueType = type.substr(0, type.length-1);
1074
+ ret = {
1075
+ intertype: 'load',
1076
+ lineNum: line.lineNum,
1077
+ assignTo: toNiceIdent(assignTo),
1078
+ ident: ident,
1079
+ type: valueType,
1080
+ valueType: valueType,
1081
+ pointerType: type,
1082
+ pointer: {
1083
+ intertype: 'value',
1084
+ ident: ident,
1085
+ type: type,
1086
+ },
1087
+ align: parseAlign(m[3])
1088
+ };
1089
+ }
1090
+ break;
1091
+ }
1092
+ case 'icmp': {
1093
+ var parts = args.split(' ');
1094
+ assert(parts.length === 4);
1095
+ ret = {
1096
+ intertype: 'mathop',
1097
+ op: 'icmp',
1098
+ variant: parts[0],
1099
+ lineNum: line.lineNum,
1100
+ assignTo: toNiceIdent(assignTo),
1101
+ params: [{
1102
+ intertype: 'value',
1103
+ ident: toNiceIdent(parts[2].substr(0, parts[2].length-1)),
1104
+ type: parts[1]
1105
+ }, {
1106
+ intertype: 'value',
1107
+ ident: toNiceIdent(parts[3]),
1108
+ type: parts[1]
1109
+ }],
1110
+ type: 'i1',
1111
+ };
1112
+ break;
1113
+ }
1114
+ default: throw 'unexpected fast path type ' + intertype;
1115
+ }
1116
+ }
1117
+ //else if (line.lineText.indexOf(' = icmp ') > 0) printErr('close: ' + JSON.stringify(line.lineText));
1045
1118
  }
1046
- });
1119
+ if (ret) {
1120
+ if (COMPILER_ASSERTIONS) {
1121
+ //printErr(['\n', dump(ret), '\n', dump(triager(tokenizer(line)))]);
1122
+ var normal = triager(tokenize(line));
1123
+ delete normal.tokens;
1124
+ delete normal.indent;
1125
+ assert(sortedJsonCompare(normal, ret), 'fast path: ' + dump(normal) + '\n vs \n' + dump(ret));
1126
+ }
1127
+ }
1128
+ return ret;
1129
+ }
1047
1130
 
1048
1131
  // Input
1049
1132
 
1050
- substrate.addItem({
1051
- llvmLines: data
1052
- }, 'LineSplitter');
1133
+ lineSplitter().forEach(function(line) {
1134
+ var item;
1135
+ if (COMPILER_FASTPATHS) {
1136
+ item = tryFastPaths(line);
1137
+ if (item) {
1138
+ finalResults.push(item);
1139
+ fastPaths++;
1140
+ return;
1141
+ }
1142
+ }
1143
+ slowPaths++;
1053
1144
 
1054
- substrate.onResult = function(result) {
1055
- if (result.tokens) result.tokens = null; // We do not need tokens, past the intertyper. Clean them up as soon as possible here.
1056
- };
1145
+ //var time = Date.now();
1146
+
1147
+ // parse out the assignment
1148
+ var indent = 0, assignTo = null;
1149
+ if (phase === 'pre') {
1150
+ var m = /^([%@\w\d\._\-]+|[%@]"[^"]+") = (.*)/.exec(line.lineText);
1151
+ if (m) {
1152
+ assignTo = m[1];
1153
+ line.lineText = m[2];
1154
+ }
1155
+ } else if (phase === 'funcs') {
1156
+ var m = /^ ([%@\w\d\._\-]+|[%@]"[^"]+") = (.*)/.exec(line.lineText);
1157
+ if (m) {
1158
+ indent = 2;
1159
+ assignTo = m[1];
1160
+ line.lineText = m[2];
1161
+ }
1162
+ }
1163
+
1164
+ var tokens = tokenize(line.lineText);
1165
+ var t = {
1166
+ tokens: tokens,
1167
+ indent: indent || line.lineText.search(/[^ ]/),
1168
+ lineNum: line.lineNum
1169
+ };
1170
+
1171
+ if (assignTo) {
1172
+ t.assignTo = t.tokens[0].text !== 'type' ? toNiceIdent(assignTo) : assignTo;
1173
+ }
1174
+ item = triager(t);
1175
+
1176
+ /*
1177
+ var type = item ? item.intertype + (item.op ? ':' + item.op : ''): 'none';
1178
+ if (!interProf[type]) interProf[type] = { ms: 0, n: 0 };
1179
+ interProf[type].ms += Date.now() - time;
1180
+ interProf[type].n++;
1181
+ */
1182
+
1183
+ if (!item) return;
1184
+ finalResults.push(item);
1185
+ if (item.tokens) item.tokens = null; // We do not need tokens, past the intertyper. Clean them up as soon as possible here.
1186
+ });
1187
+ return finalResults;
1188
+ }
1189
+
1190
+ // intertyper profiling
1057
1191
 
1058
- return substrate.solve();
1192
+ /*
1193
+ var interProf = {};
1194
+ function dumpInterProf() {
1195
+ printErr('\nintertyper/' + phase + ' (ms | n): ' + JSON.stringify(keys(interProf).sort(function(x, y) { return interProf[y].ms - interProf[x].ms }).map(function(x) { return x + ' : ' + interProf[x].ms + ' | ' + interProf[x].n }), null, ' ') + '\n');
1059
1196
  }
1197
+ */
1198
+ //var hits = 0;
1060
1199