webruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (1364) hide show
  1. checksums.yaml +7 -0
  2. data/bin/webruby +36 -0
  3. data/driver/driver.c +50 -0
  4. data/driver/main.c +40 -0
  5. data/lib/webruby/app.rb +13 -0
  6. data/lib/webruby/config.rb +61 -0
  7. data/lib/webruby/environment.rb +32 -0
  8. data/lib/webruby/rake/files.rake +66 -0
  9. data/lib/webruby/rake/general.rake +22 -0
  10. data/lib/webruby/rake/mruby.rake +44 -0
  11. data/lib/webruby/utility.rb +132 -0
  12. data/lib/webruby.rb +10 -0
  13. data/modules/emscripten/AUTHORS +89 -0
  14. data/modules/emscripten/LICENSE +68 -0
  15. data/modules/emscripten/README.markdown +14 -0
  16. data/modules/emscripten/cmake/Platform/Emscripten.cmake +61 -0
  17. data/modules/emscripten/cmake/Platform/Emscripten_unix.cmake +24 -0
  18. data/modules/emscripten/em++ +12 -0
  19. data/modules/emscripten/em++.bat +2 -0
  20. data/modules/emscripten/em-config +24 -0
  21. data/modules/emscripten/em-config.bat +2 -0
  22. data/modules/emscripten/emar +24 -0
  23. data/modules/emscripten/emar.bat +2 -0
  24. data/modules/emscripten/emcc +1744 -0
  25. data/modules/emscripten/emcc.bat +2 -0
  26. data/modules/emscripten/emcc.py +5 -0
  27. data/modules/emscripten/emconfigure +27 -0
  28. data/modules/emscripten/emconfigure.bat +2 -0
  29. data/modules/emscripten/emlibtool +11 -0
  30. data/modules/emscripten/emlibtool.bat +2 -0
  31. data/modules/emscripten/emlink.py +293 -0
  32. data/modules/emscripten/emmake +29 -0
  33. data/modules/emscripten/emmake.bat +2 -0
  34. data/modules/emscripten/emranlib +9 -0
  35. data/modules/emscripten/emranlib.bat +2 -0
  36. data/modules/emscripten/emscons +20 -0
  37. data/modules/emscripten/emscripten.py +835 -0
  38. data/modules/emscripten/patches/README +4 -0
  39. data/modules/emscripten/patches/series +2 -0
  40. data/modules/emscripten/scons-tools/closure.py +28 -0
  41. data/modules/emscripten/scons-tools/emscripten.py +359 -0
  42. data/modules/emscripten/scons-tools/llvm.py +33 -0
  43. data/modules/emscripten/src/analyzer.js +1695 -0
  44. data/modules/emscripten/src/compiler.html +48 -0
  45. data/modules/emscripten/src/compiler.js +298 -0
  46. data/modules/emscripten/src/corruptionCheck.js +98 -0
  47. data/modules/emscripten/src/determinstic.js +20 -0
  48. data/modules/emscripten/src/embind/embind.js +1677 -0
  49. data/modules/emscripten/src/embind/emval.js +283 -0
  50. data/modules/emscripten/src/experimental/allow_loopvars_from_memsetcpy_inasm.diff +97 -0
  51. data/modules/emscripten/src/experimental/batching.diff +44 -0
  52. data/modules/emscripten/src/experimental/functypeopt.diff +113 -0
  53. data/modules/emscripten/src/experimental/multiple_heaps.diff +175 -0
  54. data/modules/emscripten/src/experimental/noncallgraphprofiling.diff +197 -0
  55. data/modules/emscripten/src/experimental/optimize_memcpy_for_ta1.diff +124 -0
  56. data/modules/emscripten/src/experimental/remove__label__s.diff +140 -0
  57. data/modules/emscripten/src/experimental/renderer_cache_hash.diff +99 -0
  58. data/modules/emscripten/src/experimental/sdl_key_forwarding.diff +57 -0
  59. data/modules/emscripten/src/experimental/simplifyGeneratedFunctionsDetection.diff +336 -0
  60. data/modules/emscripten/src/experimental/stringCache.diff +147 -0
  61. data/modules/emscripten/src/fastLong.js +299 -0
  62. data/modules/emscripten/src/framework.js +257 -0
  63. data/modules/emscripten/src/gl-matrix.js +1952 -0
  64. data/modules/emscripten/src/headless.js +904 -0
  65. data/modules/emscripten/src/intertyper.js +1050 -0
  66. data/modules/emscripten/src/jsifier.js +1827 -0
  67. data/modules/emscripten/src/library.js +8270 -0
  68. data/modules/emscripten/src/library_browser.js +911 -0
  69. data/modules/emscripten/src/library_egl.js +491 -0
  70. data/modules/emscripten/src/library_gc.js +236 -0
  71. data/modules/emscripten/src/library_gl.js +4452 -0
  72. data/modules/emscripten/src/library_glfw.js +576 -0
  73. data/modules/emscripten/src/library_glut.js +449 -0
  74. data/modules/emscripten/src/library_jansson.js +320 -0
  75. data/modules/emscripten/src/library_openal.js +602 -0
  76. data/modules/emscripten/src/library_sdl.js +2024 -0
  77. data/modules/emscripten/src/library_strtok_r.c +97 -0
  78. data/modules/emscripten/src/library_xlib.js +23 -0
  79. data/modules/emscripten/src/long.js +1609 -0
  80. data/modules/emscripten/src/modules.js +491 -0
  81. data/modules/emscripten/src/parseTools.js +2474 -0
  82. data/modules/emscripten/src/postamble.js +170 -0
  83. data/modules/emscripten/src/postamble_sharedlib.js +16 -0
  84. data/modules/emscripten/src/preamble.js +914 -0
  85. data/modules/emscripten/src/preamble_sharedlib.js +25 -0
  86. data/modules/emscripten/src/relooper/README.markdown +14 -0
  87. data/modules/emscripten/src/relooper/Relooper.cpp +1236 -0
  88. data/modules/emscripten/src/relooper/Relooper.h +250 -0
  89. data/modules/emscripten/src/relooper/doit.sh +70 -0
  90. data/modules/emscripten/src/relooper/emscripten/glue.js +57 -0
  91. data/modules/emscripten/src/relooper/emscripten/test.js +44 -0
  92. data/modules/emscripten/src/relooper/fuzzer.py +116 -0
  93. data/modules/emscripten/src/relooper/ministring.h +35 -0
  94. data/modules/emscripten/src/relooper/paper.pdf +0 -0
  95. data/modules/emscripten/src/relooper/test.cpp +262 -0
  96. data/modules/emscripten/src/relooper/test.txt +155 -0
  97. data/modules/emscripten/src/relooper/test2.c +44 -0
  98. data/modules/emscripten/src/relooper/test2.txt +12 -0
  99. data/modules/emscripten/src/relooper/test3.c +42 -0
  100. data/modules/emscripten/src/relooper/test3.txt +27 -0
  101. data/modules/emscripten/src/relooper/test4.cpp +40 -0
  102. data/modules/emscripten/src/relooper/test4.txt +23 -0
  103. data/modules/emscripten/src/relooper/test5.cpp +40 -0
  104. data/modules/emscripten/src/relooper/test5.txt +32 -0
  105. data/modules/emscripten/src/relooper/test6.cpp +31 -0
  106. data/modules/emscripten/src/relooper/test6.txt +12 -0
  107. data/modules/emscripten/src/relooper/test_dead.cpp +28 -0
  108. data/modules/emscripten/src/relooper/test_dead.txt +9 -0
  109. data/modules/emscripten/src/relooper/test_debug.cpp +30 -0
  110. data/modules/emscripten/src/relooper/test_debug.txt +128 -0
  111. data/modules/emscripten/src/relooper/test_fuzz1.cpp +52 -0
  112. data/modules/emscripten/src/relooper/test_fuzz1.txt +32 -0
  113. data/modules/emscripten/src/relooper/test_fuzz2.cpp +34 -0
  114. data/modules/emscripten/src/relooper/test_fuzz2.txt +13 -0
  115. data/modules/emscripten/src/relooper/test_fuzz3.cpp +36 -0
  116. data/modules/emscripten/src/relooper/test_fuzz3.txt +9 -0
  117. data/modules/emscripten/src/relooper/test_fuzz4.cpp +38 -0
  118. data/modules/emscripten/src/relooper/test_fuzz4.txt +19 -0
  119. data/modules/emscripten/src/relooper/test_fuzz5.cpp +57 -0
  120. data/modules/emscripten/src/relooper/test_fuzz5.txt +52 -0
  121. data/modules/emscripten/src/relooper/test_fuzz6.cpp +322 -0
  122. data/modules/emscripten/src/relooper/test_fuzz6.txt +108 -0
  123. data/modules/emscripten/src/relooper/test_inf.cpp +813 -0
  124. data/modules/emscripten/src/relooper/test_inf.txt +385 -0
  125. data/modules/emscripten/src/relooper/testit.sh +62 -0
  126. data/modules/emscripten/src/relooper/updateit.sh +17 -0
  127. data/modules/emscripten/src/relooper.js +11516 -0
  128. data/modules/emscripten/src/relooper.js.raw.js +11511 -0
  129. data/modules/emscripten/src/runtime.js +546 -0
  130. data/modules/emscripten/src/settings.js +1284 -0
  131. data/modules/emscripten/src/shell.html +92 -0
  132. data/modules/emscripten/src/shell.js +153 -0
  133. data/modules/emscripten/src/shell_sharedlib.js +12 -0
  134. data/modules/emscripten/src/socket.io.js +3870 -0
  135. data/modules/emscripten/src/utility.js +379 -0
  136. data/modules/emscripten/src/wrtcp.js +821 -0
  137. data/modules/emscripten/system/include/AL/al.h +172 -0
  138. data/modules/emscripten/system/include/AL/alc.h +84 -0
  139. data/modules/emscripten/system/include/EGL/egl.h +329 -0
  140. data/modules/emscripten/system/include/EGL/eglext.h +398 -0
  141. data/modules/emscripten/system/include/EGL/eglplatform.h +141 -0
  142. data/modules/emscripten/system/include/GL/freeglut_std.h +628 -0
  143. data/modules/emscripten/system/include/GL/gl.h +2241 -0
  144. data/modules/emscripten/system/include/GL/glew.h +6 -0
  145. data/modules/emscripten/system/include/GL/glext.h +11127 -0
  146. data/modules/emscripten/system/include/GL/glfw.h +518 -0
  147. data/modules/emscripten/system/include/GL/glu.h +353 -0
  148. data/modules/emscripten/system/include/GL/glut.h +21 -0
  149. data/modules/emscripten/system/include/GLES/gl.h +770 -0
  150. data/modules/emscripten/system/include/GLES/glext.h +1278 -0
  151. data/modules/emscripten/system/include/GLES/glplatform.h +30 -0
  152. data/modules/emscripten/system/include/GLES2/gl2.h +621 -0
  153. data/modules/emscripten/system/include/GLES2/gl2ext.h +803 -0
  154. data/modules/emscripten/system/include/GLES2/gl2platform.h +30 -0
  155. data/modules/emscripten/system/include/KHR/khrplatform.h +277 -0
  156. data/modules/emscripten/system/include/SDL/COPYING +19 -0
  157. data/modules/emscripten/system/include/SDL/SDL.h +162 -0
  158. data/modules/emscripten/system/include/SDL/SDL_assert.h +241 -0
  159. data/modules/emscripten/system/include/SDL/SDL_atomic.h +318 -0
  160. data/modules/emscripten/system/include/SDL/SDL_audio.h +509 -0
  161. data/modules/emscripten/system/include/SDL/SDL_blendmode.h +60 -0
  162. data/modules/emscripten/system/include/SDL/SDL_clipboard.h +75 -0
  163. data/modules/emscripten/system/include/SDL/SDL_compat.h +365 -0
  164. data/modules/emscripten/system/include/SDL/SDL_config.h +48 -0
  165. data/modules/emscripten/system/include/SDL/SDL_config.h.in +297 -0
  166. data/modules/emscripten/system/include/SDL/SDL_config_android.h +133 -0
  167. data/modules/emscripten/system/include/SDL/SDL_config_iphoneos.h +148 -0
  168. data/modules/emscripten/system/include/SDL/SDL_config_macosx.h +172 -0
  169. data/modules/emscripten/system/include/SDL/SDL_config_minimal.h +74 -0
  170. data/modules/emscripten/system/include/SDL/SDL_config_nintendods.h +129 -0
  171. data/modules/emscripten/system/include/SDL/SDL_config_pandora.h +125 -0
  172. data/modules/emscripten/system/include/SDL/SDL_config_windows.h +207 -0
  173. data/modules/emscripten/system/include/SDL/SDL_config_wiz.h +119 -0
  174. data/modules/emscripten/system/include/SDL/SDL_copying.h +20 -0
  175. data/modules/emscripten/system/include/SDL/SDL_cpuinfo.h +150 -0
  176. data/modules/emscripten/system/include/SDL/SDL_endian.h +248 -0
  177. data/modules/emscripten/system/include/SDL/SDL_error.h +77 -0
  178. data/modules/emscripten/system/include/SDL/SDL_events.h +639 -0
  179. data/modules/emscripten/system/include/SDL/SDL_gesture.h +91 -0
  180. data/modules/emscripten/system/include/SDL/SDL_gfxPrimitives.h +246 -0
  181. data/modules/emscripten/system/include/SDL/SDL_haptic.h +1200 -0
  182. data/modules/emscripten/system/include/SDL/SDL_hints.h +206 -0
  183. data/modules/emscripten/system/include/SDL/SDL_image.h +138 -0
  184. data/modules/emscripten/system/include/SDL/SDL_input.h +87 -0
  185. data/modules/emscripten/system/include/SDL/SDL_joystick.h +208 -0
  186. data/modules/emscripten/system/include/SDL/SDL_keyboard.h +169 -0
  187. data/modules/emscripten/system/include/SDL/SDL_keycode.h +344 -0
  188. data/modules/emscripten/system/include/SDL/SDL_loadso.h +85 -0
  189. data/modules/emscripten/system/include/SDL/SDL_log.h +211 -0
  190. data/modules/emscripten/system/include/SDL/SDL_main.h +98 -0
  191. data/modules/emscripten/system/include/SDL/SDL_mixer.h +634 -0
  192. data/modules/emscripten/system/include/SDL/SDL_mouse.h +213 -0
  193. data/modules/emscripten/system/include/SDL/SDL_mutex.h +248 -0
  194. data/modules/emscripten/system/include/SDL/SDL_name.h +11 -0
  195. data/modules/emscripten/system/include/SDL/SDL_opengl.h +11116 -0
  196. data/modules/emscripten/system/include/SDL/SDL_opengles.h +38 -0
  197. data/modules/emscripten/system/include/SDL/SDL_opengles2.h +38 -0
  198. data/modules/emscripten/system/include/SDL/SDL_pixels.h +423 -0
  199. data/modules/emscripten/system/include/SDL/SDL_platform.h +160 -0
  200. data/modules/emscripten/system/include/SDL/SDL_power.h +79 -0
  201. data/modules/emscripten/system/include/SDL/SDL_quit.h +58 -0
  202. data/modules/emscripten/system/include/SDL/SDL_rect.h +136 -0
  203. data/modules/emscripten/system/include/SDL/SDL_render.h +615 -0
  204. data/modules/emscripten/system/include/SDL/SDL_revision.h +2 -0
  205. data/modules/emscripten/system/include/SDL/SDL_revision.h.orig +2 -0
  206. data/modules/emscripten/system/include/SDL/SDL_rotozoom.h +123 -0
  207. data/modules/emscripten/system/include/SDL/SDL_rwops.h +220 -0
  208. data/modules/emscripten/system/include/SDL/SDL_scancode.h +398 -0
  209. data/modules/emscripten/system/include/SDL/SDL_shape.h +147 -0
  210. data/modules/emscripten/system/include/SDL/SDL_stdinc.h +764 -0
  211. data/modules/emscripten/system/include/SDL/SDL_surface.h +499 -0
  212. data/modules/emscripten/system/include/SDL/SDL_syswm.h +241 -0
  213. data/modules/emscripten/system/include/SDL/SDL_thread.h +182 -0
  214. data/modules/emscripten/system/include/SDL/SDL_timer.h +108 -0
  215. data/modules/emscripten/system/include/SDL/SDL_touch.h +124 -0
  216. data/modules/emscripten/system/include/SDL/SDL_ttf.h +249 -0
  217. data/modules/emscripten/system/include/SDL/SDL_types.h +29 -0
  218. data/modules/emscripten/system/include/SDL/SDL_version.h +166 -0
  219. data/modules/emscripten/system/include/SDL/SDL_video.h +820 -0
  220. data/modules/emscripten/system/include/SDL/begin_code.h +135 -0
  221. data/modules/emscripten/system/include/SDL/close_code.h +37 -0
  222. data/modules/emscripten/system/include/X11/X.h +717 -0
  223. data/modules/emscripten/system/include/X11/Xatom.h +79 -0
  224. data/modules/emscripten/system/include/X11/Xfuncproto.h +127 -0
  225. data/modules/emscripten/system/include/X11/Xlib.h +4023 -0
  226. data/modules/emscripten/system/include/X11/Xosdefs.h +116 -0
  227. data/modules/emscripten/system/include/X11/Xutil.h +826 -0
  228. data/modules/emscripten/system/include/X11/keysym.h +73 -0
  229. data/modules/emscripten/system/include/X11/keysymdef.h +2389 -0
  230. data/modules/emscripten/system/include/bsd/float.h +91 -0
  231. data/modules/emscripten/system/include/bsd/readme.txt +2 -0
  232. data/modules/emscripten/system/include/bsd/sys/mman.h +180 -0
  233. data/modules/emscripten/system/include/bsd/sys/utsname.h +70 -0
  234. data/modules/emscripten/system/include/dlfcn.h +31 -0
  235. data/modules/emscripten/system/include/emscripten/bind.h +1210 -0
  236. data/modules/emscripten/system/include/emscripten/emscripten.h +388 -0
  237. data/modules/emscripten/system/include/emscripten/val.h +311 -0
  238. data/modules/emscripten/system/include/emscripten/wire.h +393 -0
  239. data/modules/emscripten/system/include/err.h +95 -0
  240. data/modules/emscripten/system/include/execinfo.h +44 -0
  241. data/modules/emscripten/system/include/features.h +3 -0
  242. data/modules/emscripten/system/include/gc.h +70 -0
  243. data/modules/emscripten/system/include/gfx/png.h +3798 -0
  244. data/modules/emscripten/system/include/gfx/pngconf.h +1665 -0
  245. data/modules/emscripten/system/include/gfx/tiff.h +654 -0
  246. data/modules/emscripten/system/include/gfx/tiffconf.h +104 -0
  247. data/modules/emscripten/system/include/gfx/tiffio.h +526 -0
  248. data/modules/emscripten/system/include/gfx/tiffvers.h +9 -0
  249. data/modules/emscripten/system/include/jansson.h +323 -0
  250. data/modules/emscripten/system/include/jansson_config.h +54 -0
  251. data/modules/emscripten/system/include/libc/_ansi.h +135 -0
  252. data/modules/emscripten/system/include/libc/_syslist.h +40 -0
  253. data/modules/emscripten/system/include/libc/alloca.h +21 -0
  254. data/modules/emscripten/system/include/libc/ar.h +69 -0
  255. data/modules/emscripten/system/include/libc/argz.h +33 -0
  256. data/modules/emscripten/system/include/libc/assert.h +46 -0
  257. data/modules/emscripten/system/include/libc/complex.h +124 -0
  258. data/modules/emscripten/system/include/libc/ctype.h +196 -0
  259. data/modules/emscripten/system/include/libc/dirent.h +16 -0
  260. data/modules/emscripten/system/include/libc/endian.h +3 -0
  261. data/modules/emscripten/system/include/libc/envlock.h +15 -0
  262. data/modules/emscripten/system/include/libc/envz.h +16 -0
  263. data/modules/emscripten/system/include/libc/errno.h +11 -0
  264. data/modules/emscripten/system/include/libc/fastmath.h +13 -0
  265. data/modules/emscripten/system/include/libc/fcntl.h +1 -0
  266. data/modules/emscripten/system/include/libc/fnmatch.h +55 -0
  267. data/modules/emscripten/system/include/libc/getopt.h +196 -0
  268. data/modules/emscripten/system/include/libc/glob.h +89 -0
  269. data/modules/emscripten/system/include/libc/grp.h +94 -0
  270. data/modules/emscripten/system/include/libc/iconv.h +62 -0
  271. data/modules/emscripten/system/include/libc/ieeefp.h +256 -0
  272. data/modules/emscripten/system/include/libc/ifaddrs.h +64 -0
  273. data/modules/emscripten/system/include/libc/inttypes.h +290 -0
  274. data/modules/emscripten/system/include/libc/iso646.h +43 -0
  275. data/modules/emscripten/system/include/libc/langinfo.h +316 -0
  276. data/modules/emscripten/system/include/libc/libgen.h +23 -0
  277. data/modules/emscripten/system/include/libc/limits.h +155 -0
  278. data/modules/emscripten/system/include/libc/locale.h +80 -0
  279. data/modules/emscripten/system/include/libc/machine/_default_types.h +121 -0
  280. data/modules/emscripten/system/include/libc/machine/_types.h +8 -0
  281. data/modules/emscripten/system/include/libc/machine/ansi.h +1 -0
  282. data/modules/emscripten/system/include/libc/machine/endian.h +31 -0
  283. data/modules/emscripten/system/include/libc/machine/fastmath.h +100 -0
  284. data/modules/emscripten/system/include/libc/machine/ieeefp.h +376 -0
  285. data/modules/emscripten/system/include/libc/machine/malloc.h +8 -0
  286. data/modules/emscripten/system/include/libc/machine/param.h +1 -0
  287. data/modules/emscripten/system/include/libc/machine/setjmp-dj.h +43 -0
  288. data/modules/emscripten/system/include/libc/machine/setjmp.h +361 -0
  289. data/modules/emscripten/system/include/libc/machine/stdlib.h +8 -0
  290. data/modules/emscripten/system/include/libc/machine/termios.h +1 -0
  291. data/modules/emscripten/system/include/libc/machine/time.h +19 -0
  292. data/modules/emscripten/system/include/libc/machine/types.h +30 -0
  293. data/modules/emscripten/system/include/libc/malloc.h +169 -0
  294. data/modules/emscripten/system/include/libc/math.h +594 -0
  295. data/modules/emscripten/system/include/libc/newlib.h +2 -0
  296. data/modules/emscripten/system/include/libc/paths.h +7 -0
  297. data/modules/emscripten/system/include/libc/process.h +44 -0
  298. data/modules/emscripten/system/include/libc/pthread.h +362 -0
  299. data/modules/emscripten/system/include/libc/pwd.h +78 -0
  300. data/modules/emscripten/system/include/libc/readme.txt +3 -0
  301. data/modules/emscripten/system/include/libc/reent.h +183 -0
  302. data/modules/emscripten/system/include/libc/regdef.h +7 -0
  303. data/modules/emscripten/system/include/libc/regex.h +102 -0
  304. data/modules/emscripten/system/include/libc/sched.h +97 -0
  305. data/modules/emscripten/system/include/libc/search.h +59 -0
  306. data/modules/emscripten/system/include/libc/setjmp.h +20 -0
  307. data/modules/emscripten/system/include/libc/signal.h +30 -0
  308. data/modules/emscripten/system/include/libc/stdarg.h +50 -0
  309. data/modules/emscripten/system/include/libc/stddef.h +64 -0
  310. data/modules/emscripten/system/include/libc/stdint.h +493 -0
  311. data/modules/emscripten/system/include/libc/stdio.h +694 -0
  312. data/modules/emscripten/system/include/libc/stdlib.h +230 -0
  313. data/modules/emscripten/system/include/libc/string.h +105 -0
  314. data/modules/emscripten/system/include/libc/strings.h +35 -0
  315. data/modules/emscripten/system/include/libc/sys/_default_fcntl.h +223 -0
  316. data/modules/emscripten/system/include/libc/sys/_types.h +93 -0
  317. data/modules/emscripten/system/include/libc/sys/cdefs.h +123 -0
  318. data/modules/emscripten/system/include/libc/sys/config.h +255 -0
  319. data/modules/emscripten/system/include/libc/sys/custom_file.h +2 -0
  320. data/modules/emscripten/system/include/libc/sys/dir.h +10 -0
  321. data/modules/emscripten/system/include/libc/sys/dirent.h +58 -0
  322. data/modules/emscripten/system/include/libc/sys/errno.h +190 -0
  323. data/modules/emscripten/system/include/libc/sys/fcntl.h +4 -0
  324. data/modules/emscripten/system/include/libc/sys/features.h +212 -0
  325. data/modules/emscripten/system/include/libc/sys/file.h +2 -0
  326. data/modules/emscripten/system/include/libc/sys/iconvnls.h +77 -0
  327. data/modules/emscripten/system/include/libc/sys/lock.h +24 -0
  328. data/modules/emscripten/system/include/libc/sys/param.h +25 -0
  329. data/modules/emscripten/system/include/libc/sys/queue.h +471 -0
  330. data/modules/emscripten/system/include/libc/sys/reent.h +843 -0
  331. data/modules/emscripten/system/include/libc/sys/resource.h +59 -0
  332. data/modules/emscripten/system/include/libc/sys/sched.h +67 -0
  333. data/modules/emscripten/system/include/libc/sys/signal.h +314 -0
  334. data/modules/emscripten/system/include/libc/sys/stat.h +222 -0
  335. data/modules/emscripten/system/include/libc/sys/stdio.h +27 -0
  336. data/modules/emscripten/system/include/libc/sys/string.h +2 -0
  337. data/modules/emscripten/system/include/libc/sys/syslimits.h +65 -0
  338. data/modules/emscripten/system/include/libc/sys/termios.h +280 -0
  339. data/modules/emscripten/system/include/libc/sys/time.h +85 -0
  340. data/modules/emscripten/system/include/libc/sys/timeb.h +39 -0
  341. data/modules/emscripten/system/include/libc/sys/times.h +28 -0
  342. data/modules/emscripten/system/include/libc/sys/ttydefaults.h +97 -0
  343. data/modules/emscripten/system/include/libc/sys/types.h +481 -0
  344. data/modules/emscripten/system/include/libc/sys/unistd.h +514 -0
  345. data/modules/emscripten/system/include/libc/sys/utime.h +26 -0
  346. data/modules/emscripten/system/include/libc/sys/wait.h +40 -0
  347. data/modules/emscripten/system/include/libc/tar.h +39 -0
  348. data/modules/emscripten/system/include/libc/termios.h +7 -0
  349. data/modules/emscripten/system/include/libc/time.h +273 -0
  350. data/modules/emscripten/system/include/libc/unctrl.h +46 -0
  351. data/modules/emscripten/system/include/libc/unistd.h +6 -0
  352. data/modules/emscripten/system/include/libc/utime.h +12 -0
  353. data/modules/emscripten/system/include/libc/utmp.h +8 -0
  354. data/modules/emscripten/system/include/libc/wchar.h +194 -0
  355. data/modules/emscripten/system/include/libc/wctype.h +47 -0
  356. data/modules/emscripten/system/include/libc/wordexp.h +53 -0
  357. data/modules/emscripten/system/include/libcxx/CREDITS.TXT +91 -0
  358. data/modules/emscripten/system/include/libcxx/LICENSE.txt +76 -0
  359. data/modules/emscripten/system/include/libcxx/__bit_reference +1268 -0
  360. data/modules/emscripten/system/include/libcxx/__config +485 -0
  361. data/modules/emscripten/system/include/libcxx/__debug +193 -0
  362. data/modules/emscripten/system/include/libcxx/__functional_03 +2130 -0
  363. data/modules/emscripten/system/include/libcxx/__functional_base +437 -0
  364. data/modules/emscripten/system/include/libcxx/__functional_base_03 +1087 -0
  365. data/modules/emscripten/system/include/libcxx/__hash_table +1945 -0
  366. data/modules/emscripten/system/include/libcxx/__locale +1435 -0
  367. data/modules/emscripten/system/include/libcxx/__mutex_base +438 -0
  368. data/modules/emscripten/system/include/libcxx/__split_buffer +654 -0
  369. data/modules/emscripten/system/include/libcxx/__sso_allocator +77 -0
  370. data/modules/emscripten/system/include/libcxx/__std_stream +317 -0
  371. data/modules/emscripten/system/include/libcxx/__tree +2293 -0
  372. data/modules/emscripten/system/include/libcxx/__tuple +305 -0
  373. data/modules/emscripten/system/include/libcxx/__tuple_03 +27 -0
  374. data/modules/emscripten/system/include/libcxx/__undef_min_max +19 -0
  375. data/modules/emscripten/system/include/libcxx/algorithm +5458 -0
  376. data/modules/emscripten/system/include/libcxx/array +341 -0
  377. data/modules/emscripten/system/include/libcxx/atomic +1521 -0
  378. data/modules/emscripten/system/include/libcxx/bitset +1081 -0
  379. data/modules/emscripten/system/include/libcxx/cassert +25 -0
  380. data/modules/emscripten/system/include/libcxx/ccomplex +29 -0
  381. data/modules/emscripten/system/include/libcxx/cctype +164 -0
  382. data/modules/emscripten/system/include/libcxx/cerrno +393 -0
  383. data/modules/emscripten/system/include/libcxx/cfenv +82 -0
  384. data/modules/emscripten/system/include/libcxx/cfloat +78 -0
  385. data/modules/emscripten/system/include/libcxx/chrono +898 -0
  386. data/modules/emscripten/system/include/libcxx/cinttypes +259 -0
  387. data/modules/emscripten/system/include/libcxx/ciso646 +25 -0
  388. data/modules/emscripten/system/include/libcxx/climits +48 -0
  389. data/modules/emscripten/system/include/libcxx/clocale +53 -0
  390. data/modules/emscripten/system/include/libcxx/cmath +1683 -0
  391. data/modules/emscripten/system/include/libcxx/codecvt +547 -0
  392. data/modules/emscripten/system/include/libcxx/complex +1526 -0
  393. data/modules/emscripten/system/include/libcxx/complex.h +35 -0
  394. data/modules/emscripten/system/include/libcxx/condition_variable +256 -0
  395. data/modules/emscripten/system/include/libcxx/csetjmp +52 -0
  396. data/modules/emscripten/system/include/libcxx/csignal +58 -0
  397. data/modules/emscripten/system/include/libcxx/cstdarg +48 -0
  398. data/modules/emscripten/system/include/libcxx/cstdbool +32 -0
  399. data/modules/emscripten/system/include/libcxx/cstddef +103 -0
  400. data/modules/emscripten/system/include/libcxx/cstdint +191 -0
  401. data/modules/emscripten/system/include/libcxx/cstdio +175 -0
  402. data/modules/emscripten/system/include/libcxx/cstdlib +172 -0
  403. data/modules/emscripten/system/include/libcxx/cstring +112 -0
  404. data/modules/emscripten/system/include/libcxx/ctgmath +29 -0
  405. data/modules/emscripten/system/include/libcxx/ctime +72 -0
  406. data/modules/emscripten/system/include/libcxx/cwchar +208 -0
  407. data/modules/emscripten/system/include/libcxx/cwctype +213 -0
  408. data/modules/emscripten/system/include/libcxx/deque +2846 -0
  409. data/modules/emscripten/system/include/libcxx/exception +250 -0
  410. data/modules/emscripten/system/include/libcxx/ext/__hash +46 -0
  411. data/modules/emscripten/system/include/libcxx/ext/hash_map +1003 -0
  412. data/modules/emscripten/system/include/libcxx/ext/hash_set +657 -0
  413. data/modules/emscripten/system/include/libcxx/forward_list +1636 -0
  414. data/modules/emscripten/system/include/libcxx/fstream +1415 -0
  415. data/modules/emscripten/system/include/libcxx/functional +2063 -0
  416. data/modules/emscripten/system/include/libcxx/future +2505 -0
  417. data/modules/emscripten/system/include/libcxx/initializer_list +105 -0
  418. data/modules/emscripten/system/include/libcxx/iomanip +504 -0
  419. data/modules/emscripten/system/include/libcxx/ios +988 -0
  420. data/modules/emscripten/system/include/libcxx/iosfwd +194 -0
  421. data/modules/emscripten/system/include/libcxx/iostream +60 -0
  422. data/modules/emscripten/system/include/libcxx/istream +1713 -0
  423. data/modules/emscripten/system/include/libcxx/iterator +1869 -0
  424. data/modules/emscripten/system/include/libcxx/limits +809 -0
  425. data/modules/emscripten/system/include/libcxx/list +2275 -0
  426. data/modules/emscripten/system/include/libcxx/locale +4591 -0
  427. data/modules/emscripten/system/include/libcxx/map +1924 -0
  428. data/modules/emscripten/system/include/libcxx/memory +5437 -0
  429. data/modules/emscripten/system/include/libcxx/mutex +566 -0
  430. data/modules/emscripten/system/include/libcxx/new +117 -0
  431. data/modules/emscripten/system/include/libcxx/numeric +197 -0
  432. data/modules/emscripten/system/include/libcxx/ostream +1286 -0
  433. data/modules/emscripten/system/include/libcxx/queue +717 -0
  434. data/modules/emscripten/system/include/libcxx/random +6750 -0
  435. data/modules/emscripten/system/include/libcxx/ratio +487 -0
  436. data/modules/emscripten/system/include/libcxx/readme.txt +1 -0
  437. data/modules/emscripten/system/include/libcxx/regex +6439 -0
  438. data/modules/emscripten/system/include/libcxx/scoped_allocator +578 -0
  439. data/modules/emscripten/system/include/libcxx/set +1025 -0
  440. data/modules/emscripten/system/include/libcxx/sstream +888 -0
  441. data/modules/emscripten/system/include/libcxx/stack +292 -0
  442. data/modules/emscripten/system/include/libcxx/stdexcept +162 -0
  443. data/modules/emscripten/system/include/libcxx/streambuf +564 -0
  444. data/modules/emscripten/system/include/libcxx/string +3987 -0
  445. data/modules/emscripten/system/include/libcxx/strstream +400 -0
  446. data/modules/emscripten/system/include/libcxx/support/solaris/floatingpoint.h +5 -0
  447. data/modules/emscripten/system/include/libcxx/support/solaris/wchar.h +38 -0
  448. data/modules/emscripten/system/include/libcxx/support/solaris/xlocale.h +146 -0
  449. data/modules/emscripten/system/include/libcxx/support/win32/limits_win32.h +79 -0
  450. data/modules/emscripten/system/include/libcxx/support/win32/locale_win32.h +116 -0
  451. data/modules/emscripten/system/include/libcxx/support/win32/math_win32.h +113 -0
  452. data/modules/emscripten/system/include/libcxx/support/win32/support.h +115 -0
  453. data/modules/emscripten/system/include/libcxx/system_error +636 -0
  454. data/modules/emscripten/system/include/libcxx/tgmath.h +29 -0
  455. data/modules/emscripten/system/include/libcxx/thread +459 -0
  456. data/modules/emscripten/system/include/libcxx/tuple +1092 -0
  457. data/modules/emscripten/system/include/libcxx/type_traits +3040 -0
  458. data/modules/emscripten/system/include/libcxx/typeindex +103 -0
  459. data/modules/emscripten/system/include/libcxx/typeinfo +124 -0
  460. data/modules/emscripten/system/include/libcxx/unordered_map +1864 -0
  461. data/modules/emscripten/system/include/libcxx/unordered_set +1144 -0
  462. data/modules/emscripten/system/include/libcxx/utility +583 -0
  463. data/modules/emscripten/system/include/libcxx/valarray +4779 -0
  464. data/modules/emscripten/system/include/libcxx/vector +3228 -0
  465. data/modules/emscripten/system/include/memory.h +10 -0
  466. data/modules/emscripten/system/include/mntent.h +23 -0
  467. data/modules/emscripten/system/include/net/arpa/inet.h +32 -0
  468. data/modules/emscripten/system/include/net/arpa/nameser.h +535 -0
  469. data/modules/emscripten/system/include/net/arpa/nameser_compat.h +187 -0
  470. data/modules/emscripten/system/include/net/if.h +87 -0
  471. data/modules/emscripten/system/include/net/netinet/in.h +166 -0
  472. data/modules/emscripten/system/include/net/netinet/tcp.h +246 -0
  473. data/modules/emscripten/system/include/net/resolv.h +389 -0
  474. data/modules/emscripten/system/include/netdb.h +94 -0
  475. data/modules/emscripten/system/include/nl_types.h +19 -0
  476. data/modules/emscripten/system/include/poll.h +3 -0
  477. data/modules/emscripten/system/include/pty.h +6 -0
  478. data/modules/emscripten/system/include/semaphore.h +31 -0
  479. data/modules/emscripten/system/include/spawn.h +105 -0
  480. data/modules/emscripten/system/include/stdbool.h +16 -0
  481. data/modules/emscripten/system/include/sys/bitypes.h +3 -0
  482. data/modules/emscripten/system/include/sys/io.h +14 -0
  483. data/modules/emscripten/system/include/sys/ioctl.h +26 -0
  484. data/modules/emscripten/system/include/sys/poll.h +31 -0
  485. data/modules/emscripten/system/include/sys/select.h +14 -0
  486. data/modules/emscripten/system/include/sys/socket.h +101 -0
  487. data/modules/emscripten/system/include/sys/socketvar.h +3 -0
  488. data/modules/emscripten/system/include/sys/statvfs.h +32 -0
  489. data/modules/emscripten/system/include/sys/sysctl.h +14 -0
  490. data/modules/emscripten/system/include/sys/uio.h +22 -0
  491. data/modules/emscripten/system/include/sys/un.h +66 -0
  492. data/modules/emscripten/system/include/sysexits.h +108 -0
  493. data/modules/emscripten/system/include/unwind.h +154 -0
  494. data/modules/emscripten/system/include/xlocale.h +47 -0
  495. data/modules/emscripten/system/include/zconf.h +428 -0
  496. data/modules/emscripten/system/include/zlib.h +1613 -0
  497. data/modules/emscripten/system/lib/compiler-rt/LICENSE.TXT +97 -0
  498. data/modules/emscripten/system/lib/compiler-rt/divdi3.c +47 -0
  499. data/modules/emscripten/system/lib/compiler-rt/int_endianness.h +116 -0
  500. data/modules/emscripten/system/lib/compiler-rt/int_lib.h +46 -0
  501. data/modules/emscripten/system/lib/compiler-rt/int_math.h +67 -0
  502. data/modules/emscripten/system/lib/compiler-rt/int_types.h +140 -0
  503. data/modules/emscripten/system/lib/compiler-rt/int_util.h +29 -0
  504. data/modules/emscripten/system/lib/compiler-rt/muldi3.c +56 -0
  505. data/modules/emscripten/system/lib/compiler-rt/readme.txt +20 -0
  506. data/modules/emscripten/system/lib/compiler-rt/udivdi3.c +36 -0
  507. data/modules/emscripten/system/lib/compiler-rt/udivmoddi4.c +251 -0
  508. data/modules/emscripten/system/lib/debugging.cpp +24 -0
  509. data/modules/emscripten/system/lib/dlmalloc.c +6299 -0
  510. data/modules/emscripten/system/lib/embind/bind.cpp +63 -0
  511. data/modules/emscripten/system/lib/libc/gen/err.c +49 -0
  512. data/modules/emscripten/system/lib/libc/gen/errx.c +49 -0
  513. data/modules/emscripten/system/lib/libc/gen/verr.c +58 -0
  514. data/modules/emscripten/system/lib/libc/gen/verrx.c +51 -0
  515. data/modules/emscripten/system/lib/libc/gen/vwarn.c +55 -0
  516. data/modules/emscripten/system/lib/libc/gen/vwarnx.c +48 -0
  517. data/modules/emscripten/system/lib/libc/gen/warn.c +49 -0
  518. data/modules/emscripten/system/lib/libc/gen/warnx.c +49 -0
  519. data/modules/emscripten/system/lib/libc/musl/COPYRIGHT +92 -0
  520. data/modules/emscripten/system/lib/libc/musl/readme.txt +1 -0
  521. data/modules/emscripten/system/lib/libc/musl/src/ctype/alpha.h +125 -0
  522. data/modules/emscripten/system/lib/libc/musl/src/ctype/iswalnum.c +7 -0
  523. data/modules/emscripten/system/lib/libc/musl/src/ctype/iswalpha.c +14 -0
  524. data/modules/emscripten/system/lib/libc/musl/src/ctype/iswblank.c +8 -0
  525. data/modules/emscripten/system/lib/libc/musl/src/ctype/iswcntrl.c +10 -0
  526. data/modules/emscripten/system/lib/libc/musl/src/ctype/iswctype.c +63 -0
  527. data/modules/emscripten/system/lib/libc/musl/src/ctype/iswdigit.c +9 -0
  528. data/modules/emscripten/system/lib/libc/musl/src/ctype/iswgraph.c +7 -0
  529. data/modules/emscripten/system/lib/libc/musl/src/ctype/iswlower.c +6 -0
  530. data/modules/emscripten/system/lib/libc/musl/src/ctype/iswprint.c +19 -0
  531. data/modules/emscripten/system/lib/libc/musl/src/ctype/iswpunct.c +12 -0
  532. data/modules/emscripten/system/lib/libc/musl/src/ctype/iswspace.c +19 -0
  533. data/modules/emscripten/system/lib/libc/musl/src/ctype/iswupper.c +6 -0
  534. data/modules/emscripten/system/lib/libc/musl/src/ctype/iswxdigit.c +7 -0
  535. data/modules/emscripten/system/lib/libc/musl/src/ctype/nonspacing.h +62 -0
  536. data/modules/emscripten/system/lib/libc/musl/src/ctype/punct.h +109 -0
  537. data/modules/emscripten/system/lib/libc/musl/src/ctype/towctrans.c +268 -0
  538. data/modules/emscripten/system/lib/libc/musl/src/ctype/wcswidth.c +8 -0
  539. data/modules/emscripten/system/lib/libc/musl/src/ctype/wctrans.c +16 -0
  540. data/modules/emscripten/system/lib/libc/musl/src/ctype/wcwidth.c +29 -0
  541. data/modules/emscripten/system/lib/libc/musl/src/ctype/wide.h +42 -0
  542. data/modules/emscripten/system/lib/libc/musl/src/internal/libc.c +22 -0
  543. data/modules/emscripten/system/lib/libc/musl/src/internal/libc.h +71 -0
  544. data/modules/emscripten/system/lib/libc/musl/src/multibyte/btowc.c +7 -0
  545. data/modules/emscripten/system/lib/libc/musl/src/multibyte/internal.c +38 -0
  546. data/modules/emscripten/system/lib/libc/musl/src/multibyte/internal.h +22 -0
  547. data/modules/emscripten/system/lib/libc/musl/src/multibyte/mblen.c +17 -0
  548. data/modules/emscripten/system/lib/libc/musl/src/multibyte/mbrlen.c +18 -0
  549. data/modules/emscripten/system/lib/libc/musl/src/multibyte/mbrtowc.c +57 -0
  550. data/modules/emscripten/system/lib/libc/musl/src/multibyte/mbsinit.c +17 -0
  551. data/modules/emscripten/system/lib/libc/musl/src/multibyte/mbsnrtowcs.c +65 -0
  552. data/modules/emscripten/system/lib/libc/musl/src/multibyte/mbsrtowcs.c +100 -0
  553. data/modules/emscripten/system/lib/libc/musl/src/multibyte/mbstowcs.c +7 -0
  554. data/modules/emscripten/system/lib/libc/musl/src/multibyte/mbtowc.c +53 -0
  555. data/modules/emscripten/system/lib/libc/musl/src/multibyte/wcrtomb.c +38 -0
  556. data/modules/emscripten/system/lib/libc/musl/src/multibyte/wcsnrtombs.c +52 -0
  557. data/modules/emscripten/system/lib/libc/musl/src/multibyte/wcsrtombs.c +58 -0
  558. data/modules/emscripten/system/lib/libc/musl/src/multibyte/wcstombs.c +7 -0
  559. data/modules/emscripten/system/lib/libc/musl/src/multibyte/wctob.c +8 -0
  560. data/modules/emscripten/system/lib/libc/musl/src/multibyte/wctomb.c +18 -0
  561. data/modules/emscripten/system/lib/libc/musl/src/string/wcpcpy.c +6 -0
  562. data/modules/emscripten/system/lib/libc/musl/src/string/wcpncpy.c +6 -0
  563. data/modules/emscripten/system/lib/libc/musl/src/string/wcscasecmp.c +7 -0
  564. data/modules/emscripten/system/lib/libc/musl/src/string/wcscasecmp_l.c +6 -0
  565. data/modules/emscripten/system/lib/libc/musl/src/string/wcscat.c +7 -0
  566. data/modules/emscripten/system/lib/libc/musl/src/string/wcschr.c +8 -0
  567. data/modules/emscripten/system/lib/libc/musl/src/string/wcscmp.c +7 -0
  568. data/modules/emscripten/system/lib/libc/musl/src/string/wcscpy.c +8 -0
  569. data/modules/emscripten/system/lib/libc/musl/src/string/wcscspn.c +10 -0
  570. data/modules/emscripten/system/lib/libc/musl/src/string/wcsdup.c +11 -0
  571. data/modules/emscripten/system/lib/libc/musl/src/string/wcslen.c +8 -0
  572. data/modules/emscripten/system/lib/libc/musl/src/string/wcsncasecmp.c +9 -0
  573. data/modules/emscripten/system/lib/libc/musl/src/string/wcsncasecmp_l.c +6 -0
  574. data/modules/emscripten/system/lib/libc/musl/src/string/wcsncat.c +10 -0
  575. data/modules/emscripten/system/lib/libc/musl/src/string/wcsncmp.c +7 -0
  576. data/modules/emscripten/system/lib/libc/musl/src/string/wcsncpy.c +9 -0
  577. data/modules/emscripten/system/lib/libc/musl/src/string/wcsnlen.c +8 -0
  578. data/modules/emscripten/system/lib/libc/musl/src/string/wcspbrk.c +7 -0
  579. data/modules/emscripten/system/lib/libc/musl/src/string/wcsrchr.c +8 -0
  580. data/modules/emscripten/system/lib/libc/musl/src/string/wcsspn.c +8 -0
  581. data/modules/emscripten/system/lib/libc/musl/src/string/wcsstr.c +108 -0
  582. data/modules/emscripten/system/lib/libc/musl/src/string/wcstok.c +12 -0
  583. data/modules/emscripten/system/lib/libc/musl/src/string/wcswcs.c +6 -0
  584. data/modules/emscripten/system/lib/libc/musl/src/string/wmemchr.c +8 -0
  585. data/modules/emscripten/system/lib/libc/musl/src/string/wmemcmp.c +8 -0
  586. data/modules/emscripten/system/lib/libc/musl/src/string/wmemcpy.c +9 -0
  587. data/modules/emscripten/system/lib/libc/musl/src/string/wmemmove.c +12 -0
  588. data/modules/emscripten/system/lib/libc/musl/src/string/wmemset.c +9 -0
  589. data/modules/emscripten/system/lib/libc/stdlib/getopt_long.c +511 -0
  590. data/modules/emscripten/system/lib/libc/stdlib/strtod.c +305 -0
  591. data/modules/emscripten/system/lib/libc.symbols +81 -0
  592. data/modules/emscripten/system/lib/libcextra.symbols +61 -0
  593. data/modules/emscripten/system/lib/libcxx/CREDITS.TXT +91 -0
  594. data/modules/emscripten/system/lib/libcxx/LICENSE.txt +76 -0
  595. data/modules/emscripten/system/lib/libcxx/algorithm.cpp +83 -0
  596. data/modules/emscripten/system/lib/libcxx/bind.cpp +30 -0
  597. data/modules/emscripten/system/lib/libcxx/chrono.cpp +132 -0
  598. data/modules/emscripten/system/lib/libcxx/condition_variable.cpp +81 -0
  599. data/modules/emscripten/system/lib/libcxx/debug.cpp +504 -0
  600. data/modules/emscripten/system/lib/libcxx/exception.cpp +226 -0
  601. data/modules/emscripten/system/lib/libcxx/future.cpp +285 -0
  602. data/modules/emscripten/system/lib/libcxx/hash.cpp +564 -0
  603. data/modules/emscripten/system/lib/libcxx/ios.cpp +455 -0
  604. data/modules/emscripten/system/lib/libcxx/iostream.cpp +68 -0
  605. data/modules/emscripten/system/lib/libcxx/locale.cpp +6093 -0
  606. data/modules/emscripten/system/lib/libcxx/memory.cpp +223 -0
  607. data/modules/emscripten/system/lib/libcxx/mutex.cpp +250 -0
  608. data/modules/emscripten/system/lib/libcxx/new.cpp +205 -0
  609. data/modules/emscripten/system/lib/libcxx/random.cpp +48 -0
  610. data/modules/emscripten/system/lib/libcxx/readme.txt +1 -0
  611. data/modules/emscripten/system/lib/libcxx/regex.cpp +325 -0
  612. data/modules/emscripten/system/lib/libcxx/stdexcept.cpp +196 -0
  613. data/modules/emscripten/system/lib/libcxx/string.cpp +687 -0
  614. data/modules/emscripten/system/lib/libcxx/strstream.cpp +329 -0
  615. data/modules/emscripten/system/lib/libcxx/support/solaris/README +4 -0
  616. data/modules/emscripten/system/lib/libcxx/support/solaris/mbsnrtowcs.inc +76 -0
  617. data/modules/emscripten/system/lib/libcxx/support/solaris/wcsnrtombs.inc +93 -0
  618. data/modules/emscripten/system/lib/libcxx/support/solaris/xlocale.c +245 -0
  619. data/modules/emscripten/system/lib/libcxx/support/win32/locale_win32.cpp +94 -0
  620. data/modules/emscripten/system/lib/libcxx/support/win32/support.cpp +70 -0
  621. data/modules/emscripten/system/lib/libcxx/symbols +2927 -0
  622. data/modules/emscripten/system/lib/libcxx/system_error.cpp +201 -0
  623. data/modules/emscripten/system/lib/libcxx/thread.cpp +208 -0
  624. data/modules/emscripten/system/lib/libcxx/typeinfo.cpp +60 -0
  625. data/modules/emscripten/system/lib/libcxx/utility.cpp +17 -0
  626. data/modules/emscripten/system/lib/libcxx/valarray.cpp +54 -0
  627. data/modules/emscripten/system/lib/libcxxabi/CREDITS.TXT +38 -0
  628. data/modules/emscripten/system/lib/libcxxabi/LICENSE.TXT +76 -0
  629. data/modules/emscripten/system/lib/libcxxabi/include/cxa_demangle.h +167 -0
  630. data/modules/emscripten/system/lib/libcxxabi/include/cxxabi.h +175 -0
  631. data/modules/emscripten/system/lib/libcxxabi/lib/buildit +99 -0
  632. data/modules/emscripten/system/lib/libcxxabi/readme.txt +1 -0
  633. data/modules/emscripten/system/lib/libcxxabi/src/abort_message.cpp +50 -0
  634. data/modules/emscripten/system/lib/libcxxabi/src/abort_message.h +33 -0
  635. data/modules/emscripten/system/lib/libcxxabi/src/cxa_aux_runtime.cpp +34 -0
  636. data/modules/emscripten/system/lib/libcxxabi/src/cxa_demangle.cpp +11036 -0
  637. data/modules/emscripten/system/lib/libcxxabi/src/cxa_exception.cpp +622 -0
  638. data/modules/emscripten/system/lib/libcxxabi/src/cxa_exception.hpp +123 -0
  639. data/modules/emscripten/system/lib/libcxxabi/src/cxa_exception_storage.cpp +91 -0
  640. data/modules/emscripten/system/lib/libcxxabi/src/cxa_guard.cpp +231 -0
  641. data/modules/emscripten/system/lib/libcxxabi/src/cxa_handlers.cpp +125 -0
  642. data/modules/emscripten/system/lib/libcxxabi/src/cxa_handlers.hpp +54 -0
  643. data/modules/emscripten/system/lib/libcxxabi/src/cxa_new_delete.cpp +242 -0
  644. data/modules/emscripten/system/lib/libcxxabi/src/cxa_personality.cpp +1055 -0
  645. data/modules/emscripten/system/lib/libcxxabi/src/cxa_unexpected.cpp +27 -0
  646. data/modules/emscripten/system/lib/libcxxabi/src/cxa_vector.cpp +367 -0
  647. data/modules/emscripten/system/lib/libcxxabi/src/cxa_virtual.cpp +31 -0
  648. data/modules/emscripten/system/lib/libcxxabi/src/exception.cpp +41 -0
  649. data/modules/emscripten/system/lib/libcxxabi/src/fallback_malloc.ipp +174 -0
  650. data/modules/emscripten/system/lib/libcxxabi/src/private_typeinfo.cpp +1146 -0
  651. data/modules/emscripten/system/lib/libcxxabi/src/private_typeinfo.h +248 -0
  652. data/modules/emscripten/system/lib/libcxxabi/src/stdexcept.cpp +169 -0
  653. data/modules/emscripten/system/lib/libcxxabi/src/typeinfo.cpp +53 -0
  654. data/modules/emscripten/system/lib/libcxxabi/symbols +236 -0
  655. data/modules/emscripten/system/lib/sdl.cpp +13 -0
  656. data/modules/emscripten/system/lib/sdl.symbols +1 -0
  657. data/modules/emscripten/tests/hello_world.js +92 -0
  658. data/modules/emscripten/third_party/CppHeaderParser/CppHeaderParser/CppHeaderParser.py +2347 -0
  659. data/modules/emscripten/third_party/CppHeaderParser/CppHeaderParser/__init__.py +4 -0
  660. data/modules/emscripten/third_party/CppHeaderParser/CppHeaderParser/doc/CppHeaderParser.html +657 -0
  661. data/modules/emscripten/third_party/CppHeaderParser/CppHeaderParser/examples/SampleClass.h +147 -0
  662. data/modules/emscripten/third_party/CppHeaderParser/CppHeaderParser/examples/readSampleClass.py +74 -0
  663. data/modules/emscripten/third_party/CppHeaderParser/PKG-INFO +249 -0
  664. data/modules/emscripten/third_party/CppHeaderParser/README.html +544 -0
  665. data/modules/emscripten/third_party/CppHeaderParser/README.txt +226 -0
  666. data/modules/emscripten/third_party/CppHeaderParser/setup.py +43 -0
  667. data/modules/emscripten/third_party/ansidecl.h +371 -0
  668. data/modules/emscripten/third_party/closure-compiler/COPYING +202 -0
  669. data/modules/emscripten/third_party/closure-compiler/README +292 -0
  670. data/modules/emscripten/third_party/closure-compiler/compiler.jar +0 -0
  671. data/modules/emscripten/third_party/closure-compiler/readme.txt +3 -0
  672. data/modules/emscripten/third_party/cp-demangle.h +161 -0
  673. data/modules/emscripten/third_party/demangle.h +549 -0
  674. data/modules/emscripten/third_party/demangler.py +49 -0
  675. data/modules/emscripten/third_party/gcc_demangler.c +4226 -0
  676. data/modules/emscripten/third_party/gcc_demangler.js +21282 -0
  677. data/modules/emscripten/third_party/jni/emjvm.cpp +133 -0
  678. data/modules/emscripten/third_party/jni/emjvm.h +8 -0
  679. data/modules/emscripten/third_party/jni/emjvm.js +185 -0
  680. data/modules/emscripten/third_party/jni/jni.h +1154 -0
  681. data/modules/emscripten/third_party/libiberty.h +634 -0
  682. data/modules/emscripten/third_party/lzma.js/README.markdown +37 -0
  683. data/modules/emscripten/third_party/lzma.js/doit.sh +37 -0
  684. data/modules/emscripten/third_party/lzma.js/lzip/AUTHORS +7 -0
  685. data/modules/emscripten/third_party/lzma.js/lzip/COPYING +676 -0
  686. data/modules/emscripten/third_party/lzma.js/lzip/ChangeLog +201 -0
  687. data/modules/emscripten/third_party/lzma.js/lzip/INSTALL +56 -0
  688. data/modules/emscripten/third_party/lzma.js/lzip/Makefile +160 -0
  689. data/modules/emscripten/third_party/lzma.js/lzip/Makefile.in +138 -0
  690. data/modules/emscripten/third_party/lzma.js/lzip/NEWS +22 -0
  691. data/modules/emscripten/third_party/lzma.js/lzip/README +77 -0
  692. data/modules/emscripten/third_party/lzma.js/lzip/arg_parser.cc +204 -0
  693. data/modules/emscripten/third_party/lzma.js/lzip/arg_parser.h +106 -0
  694. data/modules/emscripten/third_party/lzma.js/lzip/configure +192 -0
  695. data/modules/emscripten/third_party/lzma.js/lzip/decoder.cc +252 -0
  696. data/modules/emscripten/third_party/lzma.js/lzip/decoder.h +268 -0
  697. data/modules/emscripten/third_party/lzma.js/lzip/encoder.cc +643 -0
  698. data/modules/emscripten/third_party/lzma.js/lzip/encoder.h +582 -0
  699. data/modules/emscripten/third_party/lzma.js/lzip/fast_encoder.cc +378 -0
  700. data/modules/emscripten/third_party/lzma.js/lzip/fast_encoder.h +171 -0
  701. data/modules/emscripten/third_party/lzma.js/lzip/lzip.h +264 -0
  702. data/modules/emscripten/third_party/lzma.js/lzip/main.cc +545 -0
  703. data/modules/emscripten/third_party/lzma.js/lzma-decoder.js +27 -0
  704. data/modules/emscripten/third_party/lzma.js/lzma-full.js +27 -0
  705. data/modules/emscripten/third_party/lzma.js/native_test.sh +5 -0
  706. data/modules/emscripten/third_party/lzma.js/post.js +13 -0
  707. data/modules/emscripten/third_party/lzma.js/pre.js +13 -0
  708. data/modules/emscripten/third_party/lzma.js/test-decoder.js +39 -0
  709. data/modules/emscripten/third_party/lzma.js/test-full.html +9 -0
  710. data/modules/emscripten/third_party/lzma.js/test-full.js +78 -0
  711. data/modules/emscripten/third_party/ply/ANNOUNCE +40 -0
  712. data/modules/emscripten/third_party/ply/CHANGES +1093 -0
  713. data/modules/emscripten/third_party/ply/PKG-INFO +22 -0
  714. data/modules/emscripten/third_party/ply/README +271 -0
  715. data/modules/emscripten/third_party/ply/TODO +16 -0
  716. data/modules/emscripten/third_party/ply/doc/internal.html +874 -0
  717. data/modules/emscripten/third_party/ply/doc/makedoc.py +194 -0
  718. data/modules/emscripten/third_party/ply/doc/ply.html +3262 -0
  719. data/modules/emscripten/third_party/ply/example/BASIC/README +79 -0
  720. data/modules/emscripten/third_party/ply/example/BASIC/basic.py +71 -0
  721. data/modules/emscripten/third_party/ply/example/BASIC/basiclex.py +74 -0
  722. data/modules/emscripten/third_party/ply/example/BASIC/basiclog.py +79 -0
  723. data/modules/emscripten/third_party/ply/example/BASIC/basinterp.py +441 -0
  724. data/modules/emscripten/third_party/ply/example/BASIC/basparse.py +424 -0
  725. data/modules/emscripten/third_party/ply/example/BASIC/dim.bas +14 -0
  726. data/modules/emscripten/third_party/ply/example/BASIC/func.bas +5 -0
  727. data/modules/emscripten/third_party/ply/example/BASIC/gcd.bas +22 -0
  728. data/modules/emscripten/third_party/ply/example/BASIC/gosub.bas +13 -0
  729. data/modules/emscripten/third_party/ply/example/BASIC/hello.bas +4 -0
  730. data/modules/emscripten/third_party/ply/example/BASIC/linear.bas +17 -0
  731. data/modules/emscripten/third_party/ply/example/BASIC/maxsin.bas +12 -0
  732. data/modules/emscripten/third_party/ply/example/BASIC/powers.bas +13 -0
  733. data/modules/emscripten/third_party/ply/example/BASIC/rand.bas +4 -0
  734. data/modules/emscripten/third_party/ply/example/BASIC/sales.bas +20 -0
  735. data/modules/emscripten/third_party/ply/example/BASIC/sears.bas +18 -0
  736. data/modules/emscripten/third_party/ply/example/BASIC/sqrt1.bas +5 -0
  737. data/modules/emscripten/third_party/ply/example/BASIC/sqrt2.bas +4 -0
  738. data/modules/emscripten/third_party/ply/example/GardenSnake/GardenSnake.py +709 -0
  739. data/modules/emscripten/third_party/ply/example/GardenSnake/README +5 -0
  740. data/modules/emscripten/third_party/ply/example/README +10 -0
  741. data/modules/emscripten/third_party/ply/example/ansic/README +2 -0
  742. data/modules/emscripten/third_party/ply/example/ansic/clex.py +164 -0
  743. data/modules/emscripten/third_party/ply/example/ansic/cparse.py +863 -0
  744. data/modules/emscripten/third_party/ply/example/calc/calc.py +107 -0
  745. data/modules/emscripten/third_party/ply/example/calcdebug/calc.py +113 -0
  746. data/modules/emscripten/third_party/ply/example/classcalc/calc.py +157 -0
  747. data/modules/emscripten/third_party/ply/example/cleanup.sh +2 -0
  748. data/modules/emscripten/third_party/ply/example/closurecalc/calc.py +130 -0
  749. data/modules/emscripten/third_party/ply/example/hedit/hedit.py +48 -0
  750. data/modules/emscripten/third_party/ply/example/newclasscalc/calc.py +160 -0
  751. data/modules/emscripten/third_party/ply/example/optcalc/README +9 -0
  752. data/modules/emscripten/third_party/ply/example/optcalc/calc.py +119 -0
  753. data/modules/emscripten/third_party/ply/example/unicalc/calc.py +117 -0
  754. data/modules/emscripten/third_party/ply/example/yply/README +41 -0
  755. data/modules/emscripten/third_party/ply/example/yply/ylex.py +112 -0
  756. data/modules/emscripten/third_party/ply/example/yply/yparse.py +217 -0
  757. data/modules/emscripten/third_party/ply/example/yply/yply.py +53 -0
  758. data/modules/emscripten/third_party/ply/ply/__init__.py +4 -0
  759. data/modules/emscripten/third_party/ply/ply/cpp.py +898 -0
  760. data/modules/emscripten/third_party/ply/ply/ctokens.py +133 -0
  761. data/modules/emscripten/third_party/ply/ply/lex.py +1058 -0
  762. data/modules/emscripten/third_party/ply/ply/yacc.py +3276 -0
  763. data/modules/emscripten/third_party/ply/setup.py +31 -0
  764. data/modules/emscripten/third_party/ply/test/README +7 -0
  765. data/modules/emscripten/third_party/ply/test/calclex.py +49 -0
  766. data/modules/emscripten/third_party/ply/test/cleanup.sh +4 -0
  767. data/modules/emscripten/third_party/ply/test/lex_closure.py +54 -0
  768. data/modules/emscripten/third_party/ply/test/lex_doc1.py +26 -0
  769. data/modules/emscripten/third_party/ply/test/lex_dup1.py +29 -0
  770. data/modules/emscripten/third_party/ply/test/lex_dup2.py +33 -0
  771. data/modules/emscripten/third_party/ply/test/lex_dup3.py +31 -0
  772. data/modules/emscripten/third_party/ply/test/lex_empty.py +20 -0
  773. data/modules/emscripten/third_party/ply/test/lex_error1.py +24 -0
  774. data/modules/emscripten/third_party/ply/test/lex_error2.py +26 -0
  775. data/modules/emscripten/third_party/ply/test/lex_error3.py +27 -0
  776. data/modules/emscripten/third_party/ply/test/lex_error4.py +27 -0
  777. data/modules/emscripten/third_party/ply/test/lex_hedit.py +47 -0
  778. data/modules/emscripten/third_party/ply/test/lex_ignore.py +31 -0
  779. data/modules/emscripten/third_party/ply/test/lex_ignore2.py +29 -0
  780. data/modules/emscripten/third_party/ply/test/lex_literal1.py +25 -0
  781. data/modules/emscripten/third_party/ply/test/lex_literal2.py +25 -0
  782. data/modules/emscripten/third_party/ply/test/lex_many_tokens.py +27 -0
  783. data/modules/emscripten/third_party/ply/test/lex_module.py +10 -0
  784. data/modules/emscripten/third_party/ply/test/lex_module_import.py +42 -0
  785. data/modules/emscripten/third_party/ply/test/lex_object.py +55 -0
  786. data/modules/emscripten/third_party/ply/test/lex_opt_alias.py +54 -0
  787. data/modules/emscripten/third_party/ply/test/lex_optimize.py +50 -0
  788. data/modules/emscripten/third_party/ply/test/lex_optimize2.py +50 -0
  789. data/modules/emscripten/third_party/ply/test/lex_optimize3.py +52 -0
  790. data/modules/emscripten/third_party/ply/test/lex_re1.py +27 -0
  791. data/modules/emscripten/third_party/ply/test/lex_re2.py +27 -0
  792. data/modules/emscripten/third_party/ply/test/lex_re3.py +29 -0
  793. data/modules/emscripten/third_party/ply/test/lex_rule1.py +27 -0
  794. data/modules/emscripten/third_party/ply/test/lex_rule2.py +29 -0
  795. data/modules/emscripten/third_party/ply/test/lex_rule3.py +27 -0
  796. data/modules/emscripten/third_party/ply/test/lex_state1.py +40 -0
  797. data/modules/emscripten/third_party/ply/test/lex_state2.py +40 -0
  798. data/modules/emscripten/third_party/ply/test/lex_state3.py +42 -0
  799. data/modules/emscripten/third_party/ply/test/lex_state4.py +41 -0
  800. data/modules/emscripten/third_party/ply/test/lex_state5.py +40 -0
  801. data/modules/emscripten/third_party/ply/test/lex_state_noerror.py +39 -0
  802. data/modules/emscripten/third_party/ply/test/lex_state_norule.py +40 -0
  803. data/modules/emscripten/third_party/ply/test/lex_state_try.py +45 -0
  804. data/modules/emscripten/third_party/ply/test/lex_token1.py +19 -0
  805. data/modules/emscripten/third_party/ply/test/lex_token2.py +22 -0
  806. data/modules/emscripten/third_party/ply/test/lex_token3.py +24 -0
  807. data/modules/emscripten/third_party/ply/test/lex_token4.py +26 -0
  808. data/modules/emscripten/third_party/ply/test/lex_token5.py +31 -0
  809. data/modules/emscripten/third_party/ply/test/lex_token_dup.py +29 -0
  810. data/modules/emscripten/third_party/ply/test/testlex.py +606 -0
  811. data/modules/emscripten/third_party/ply/test/testyacc.py +347 -0
  812. data/modules/emscripten/third_party/ply/test/yacc_badargs.py +68 -0
  813. data/modules/emscripten/third_party/ply/test/yacc_badid.py +77 -0
  814. data/modules/emscripten/third_party/ply/test/yacc_badprec.py +64 -0
  815. data/modules/emscripten/third_party/ply/test/yacc_badprec2.py +68 -0
  816. data/modules/emscripten/third_party/ply/test/yacc_badprec3.py +68 -0
  817. data/modules/emscripten/third_party/ply/test/yacc_badrule.py +68 -0
  818. data/modules/emscripten/third_party/ply/test/yacc_badtok.py +68 -0
  819. data/modules/emscripten/third_party/ply/test/yacc_dup.py +68 -0
  820. data/modules/emscripten/third_party/ply/test/yacc_error1.py +68 -0
  821. data/modules/emscripten/third_party/ply/test/yacc_error2.py +68 -0
  822. data/modules/emscripten/third_party/ply/test/yacc_error3.py +67 -0
  823. data/modules/emscripten/third_party/ply/test/yacc_error4.py +72 -0
  824. data/modules/emscripten/third_party/ply/test/yacc_inf.py +56 -0
  825. data/modules/emscripten/third_party/ply/test/yacc_literal.py +69 -0
  826. data/modules/emscripten/third_party/ply/test/yacc_misplaced.py +68 -0
  827. data/modules/emscripten/third_party/ply/test/yacc_missing1.py +68 -0
  828. data/modules/emscripten/third_party/ply/test/yacc_nested.py +33 -0
  829. data/modules/emscripten/third_party/ply/test/yacc_nodoc.py +67 -0
  830. data/modules/emscripten/third_party/ply/test/yacc_noerror.py +66 -0
  831. data/modules/emscripten/third_party/ply/test/yacc_nop.py +68 -0
  832. data/modules/emscripten/third_party/ply/test/yacc_notfunc.py +66 -0
  833. data/modules/emscripten/third_party/ply/test/yacc_notok.py +67 -0
  834. data/modules/emscripten/third_party/ply/test/yacc_prec1.py +68 -0
  835. data/modules/emscripten/third_party/ply/test/yacc_rr.py +72 -0
  836. data/modules/emscripten/third_party/ply/test/yacc_rr_unused.py +30 -0
  837. data/modules/emscripten/third_party/ply/test/yacc_simple.py +68 -0
  838. data/modules/emscripten/third_party/ply/test/yacc_sr.py +63 -0
  839. data/modules/emscripten/third_party/ply/test/yacc_term1.py +68 -0
  840. data/modules/emscripten/third_party/ply/test/yacc_unused.py +77 -0
  841. data/modules/emscripten/third_party/ply/test/yacc_unused_rule.py +72 -0
  842. data/modules/emscripten/third_party/ply/test/yacc_uprec.py +63 -0
  843. data/modules/emscripten/third_party/ply/test/yacc_uprec2.py +63 -0
  844. data/modules/emscripten/third_party/readme.txt +7 -0
  845. data/modules/emscripten/third_party/websockify/CHANGES.txt +23 -0
  846. data/modules/emscripten/third_party/websockify/LICENSE.txt +16 -0
  847. data/modules/emscripten/third_party/websockify/MANIFEST.in +1 -0
  848. data/modules/emscripten/third_party/websockify/Makefile +11 -0
  849. data/modules/emscripten/third_party/websockify/README.md +168 -0
  850. data/modules/emscripten/third_party/websockify/Windows/Windows Service Readme.txt +39 -0
  851. data/modules/emscripten/third_party/websockify/Windows/noVNC Websocket Service Project/Program.cs +24 -0
  852. data/modules/emscripten/third_party/websockify/Windows/noVNC Websocket Service Project/ProjectInstaller.Designer.cs +61 -0
  853. data/modules/emscripten/third_party/websockify/Windows/noVNC Websocket Service Project/ProjectInstaller.cs +19 -0
  854. data/modules/emscripten/third_party/websockify/Windows/noVNC Websocket Service Project/ProjectInstaller.resx +129 -0
  855. data/modules/emscripten/third_party/websockify/Windows/noVNC Websocket Service Project/Properties/AssemblyInfo.cs +36 -0
  856. data/modules/emscripten/third_party/websockify/Windows/noVNC Websocket Service Project/Service1.Designer.cs +37 -0
  857. data/modules/emscripten/third_party/websockify/Windows/noVNC Websocket Service Project/Service1.cs +41 -0
  858. data/modules/emscripten/third_party/websockify/Windows/noVNC Websocket Service Project/noVNC Websocket.csproj +75 -0
  859. data/modules/emscripten/third_party/websockify/Windows/noVNC Websocket Service Project/noVNC Websocket.sln +20 -0
  860. data/modules/emscripten/third_party/websockify/docs/LICENSE.GPL-3 +621 -0
  861. data/modules/emscripten/third_party/websockify/docs/LICENSE.LGPL-3 +165 -0
  862. data/modules/emscripten/third_party/websockify/docs/LICENSE.MPL-2.0 +373 -0
  863. data/modules/emscripten/third_party/websockify/docs/TODO +9 -0
  864. data/modules/emscripten/third_party/websockify/docs/flash_policy.txt +4 -0
  865. data/modules/emscripten/third_party/websockify/docs/latency_results.txt +114 -0
  866. data/modules/emscripten/third_party/websockify/docs/notes +17 -0
  867. data/modules/emscripten/third_party/websockify/docs/release.txt +9 -0
  868. data/modules/emscripten/third_party/websockify/docs/websockify.1 +110 -0
  869. data/modules/emscripten/third_party/websockify/include/VT100.js +919 -0
  870. data/modules/emscripten/third_party/websockify/include/base64.js +114 -0
  871. data/modules/emscripten/third_party/websockify/include/keysym.js +99 -0
  872. data/modules/emscripten/third_party/websockify/include/util.js +359 -0
  873. data/modules/emscripten/third_party/websockify/include/web-socket-js/README.txt +109 -0
  874. data/modules/emscripten/third_party/websockify/include/web-socket-js/WebSocketMain.swf +0 -0
  875. data/modules/emscripten/third_party/websockify/include/web-socket-js/swfobject.js +4 -0
  876. data/modules/emscripten/third_party/websockify/include/web-socket-js/web_socket.js +391 -0
  877. data/modules/emscripten/third_party/websockify/include/websock.js +422 -0
  878. data/modules/emscripten/third_party/websockify/include/webutil.js +216 -0
  879. data/modules/emscripten/third_party/websockify/include/wsirc.js +235 -0
  880. data/modules/emscripten/third_party/websockify/include/wstelnet.js +335 -0
  881. data/modules/emscripten/third_party/websockify/other/Makefile +14 -0
  882. data/modules/emscripten/third_party/websockify/other/README.md +51 -0
  883. data/modules/emscripten/third_party/websockify/other/launch.sh +108 -0
  884. data/modules/emscripten/third_party/websockify/other/project.clj +13 -0
  885. data/modules/emscripten/third_party/websockify/other/websocket.c +802 -0
  886. data/modules/emscripten/third_party/websockify/other/websocket.h +84 -0
  887. data/modules/emscripten/third_party/websockify/other/websocket.rb +456 -0
  888. data/modules/emscripten/third_party/websockify/other/websockify.c +385 -0
  889. data/modules/emscripten/third_party/websockify/other/websockify.clj +233 -0
  890. data/modules/emscripten/third_party/websockify/other/websockify.js +196 -0
  891. data/modules/emscripten/third_party/websockify/other/websockify.rb +171 -0
  892. data/modules/emscripten/third_party/websockify/other/wswrap +22 -0
  893. data/modules/emscripten/third_party/websockify/rebind +18 -0
  894. data/modules/emscripten/third_party/websockify/rebind.c +94 -0
  895. data/modules/emscripten/third_party/websockify/run +5 -0
  896. data/modules/emscripten/third_party/websockify/setup.py +30 -0
  897. data/modules/emscripten/third_party/websockify/tests/b64_vs_utf8.py +29 -0
  898. data/modules/emscripten/third_party/websockify/tests/base64.html +91 -0
  899. data/modules/emscripten/third_party/websockify/tests/base64.js +12 -0
  900. data/modules/emscripten/third_party/websockify/tests/echo.html +148 -0
  901. data/modules/emscripten/third_party/websockify/tests/echo.py +75 -0
  902. data/modules/emscripten/third_party/websockify/tests/echo.rb +62 -0
  903. data/modules/emscripten/third_party/websockify/tests/latency.html +290 -0
  904. data/modules/emscripten/third_party/websockify/tests/latency.py +75 -0
  905. data/modules/emscripten/third_party/websockify/tests/load.html +250 -0
  906. data/modules/emscripten/third_party/websockify/tests/load.py +167 -0
  907. data/modules/emscripten/third_party/websockify/tests/plain_echo.html +168 -0
  908. data/modules/emscripten/third_party/websockify/tests/simple.html +68 -0
  909. data/modules/emscripten/third_party/websockify/tests/utf8-list.py +22 -0
  910. data/modules/emscripten/third_party/websockify/websockify/__init__.py +2 -0
  911. data/modules/emscripten/third_party/websockify/websockify/websocket.py +982 -0
  912. data/modules/emscripten/third_party/websockify/websockify/websocketproxy.py +393 -0
  913. data/modules/emscripten/third_party/websockify/websockify.py +5 -0
  914. data/modules/emscripten/third_party/websockify/wsirc.html +99 -0
  915. data/modules/emscripten/third_party/websockify/wstelnet.html +74 -0
  916. data/modules/emscripten/tools/__init__.py +0 -0
  917. data/modules/emscripten/tools/__init__.pyc +0 -0
  918. data/modules/emscripten/tools/autodebugger.py +289 -0
  919. data/modules/emscripten/tools/autodebugger_c.py +37 -0
  920. data/modules/emscripten/tools/autodebugger_indenter.py +18 -0
  921. data/modules/emscripten/tools/autodebugger_js.py +47 -0
  922. data/modules/emscripten/tools/autodediffer.py +60 -0
  923. data/modules/emscripten/tools/bindings_generator.py +832 -0
  924. data/modules/emscripten/tools/bisect_pair.py +88 -0
  925. data/modules/emscripten/tools/cache.py +198 -0
  926. data/modules/emscripten/tools/cache.pyc +0 -0
  927. data/modules/emscripten/tools/clean_webconsole.py +34 -0
  928. data/modules/emscripten/tools/crunch-worker.js +124 -0
  929. data/modules/emscripten/tools/diff_autodebugger.py +15 -0
  930. data/modules/emscripten/tools/eliminator/asm-eliminator-test-output.js +5129 -0
  931. data/modules/emscripten/tools/eliminator/asm-eliminator-test.js +6861 -0
  932. data/modules/emscripten/tools/eliminator/eliminator-test-output.js +6122 -0
  933. data/modules/emscripten/tools/eliminator/eliminator-test.js +8856 -0
  934. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/README.html +888 -0
  935. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/README.org +463 -0
  936. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/bin/uglifyjs +317 -0
  937. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/docstyle.css +75 -0
  938. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/lib/object-ast.js +75 -0
  939. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/lib/parse-js.js +1363 -0
  940. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/lib/process.js +2005 -0
  941. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/lib/squeeze-more.js +51 -0
  942. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/package.json +22 -0
  943. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/beautify.js +28 -0
  944. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/testparser.js +402 -0
  945. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/array1.js +1 -0
  946. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/array2.js +1 -0
  947. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/array3.js +1 -0
  948. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/array4.js +1 -0
  949. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/assignment.js +1 -0
  950. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/concatstring.js +1 -0
  951. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/const.js +1 -0
  952. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/empty-blocks.js +1 -0
  953. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/forstatement.js +1 -0
  954. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/if.js +1 -0
  955. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/ifreturn.js +1 -0
  956. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/ifreturn2.js +1 -0
  957. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue10.js +1 -0
  958. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue11.js +1 -0
  959. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue13.js +1 -0
  960. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue14.js +1 -0
  961. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue16.js +1 -0
  962. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue17.js +1 -0
  963. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue20.js +1 -0
  964. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue21.js +1 -0
  965. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue25.js +1 -0
  966. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue27.js +1 -0
  967. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue28.js +1 -0
  968. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue29.js +1 -0
  969. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue30.js +1 -0
  970. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue34.js +1 -0
  971. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue4.js +1 -0
  972. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue48.js +1 -0
  973. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue50.js +1 -0
  974. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue53.js +1 -0
  975. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue54.1.js +1 -0
  976. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue68.js +1 -0
  977. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue69.js +1 -0
  978. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/issue9.js +1 -0
  979. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/mangle.js +1 -0
  980. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/strict-equals.js +1 -0
  981. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/var.js +1 -0
  982. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/expected/with.js +1 -0
  983. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/array1.js +3 -0
  984. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/array2.js +4 -0
  985. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/array3.js +4 -0
  986. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/array4.js +6 -0
  987. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/assignment.js +20 -0
  988. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/concatstring.js +3 -0
  989. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/const.js +5 -0
  990. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/empty-blocks.js +4 -0
  991. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/forstatement.js +10 -0
  992. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/if.js +6 -0
  993. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/ifreturn.js +9 -0
  994. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/ifreturn2.js +16 -0
  995. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue10.js +1 -0
  996. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue11.js +3 -0
  997. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue13.js +1 -0
  998. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue14.js +1 -0
  999. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue16.js +1 -0
  1000. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue17.js +4 -0
  1001. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue20.js +1 -0
  1002. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue21.js +6 -0
  1003. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue25.js +7 -0
  1004. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue27.js +1 -0
  1005. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue28.js +3 -0
  1006. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue29.js +1 -0
  1007. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue30.js +3 -0
  1008. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue34.js +3 -0
  1009. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue4.js +3 -0
  1010. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue48.js +1 -0
  1011. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue50.js +9 -0
  1012. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue53.js +1 -0
  1013. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue54.1.js +3 -0
  1014. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue68.js +5 -0
  1015. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue69.js +1 -0
  1016. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/issue9.js +4 -0
  1017. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/mangle.js +5 -0
  1018. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/strict-equals.js +3 -0
  1019. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/var.js +3 -0
  1020. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/compress/test/with.js +2 -0
  1021. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/test/unit/scripts.js +55 -0
  1022. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/tmp/hoist.js +33 -0
  1023. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/tmp/instrument.js +97 -0
  1024. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/tmp/instrument2.js +138 -0
  1025. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/tmp/test.js +16 -0
  1026. data/modules/emscripten/tools/eliminator/node_modules/uglify-js/uglify-js.js +17 -0
  1027. data/modules/emscripten/tools/eliminator/safe-eliminator-test-output.js +85 -0
  1028. data/modules/emscripten/tools/eliminator/safe-eliminator-test.js +103 -0
  1029. data/modules/emscripten/tools/emconfiguren.py +19 -0
  1030. data/modules/emscripten/tools/emmaken.py +230 -0
  1031. data/modules/emscripten/tools/emmakenxx.py +18 -0
  1032. data/modules/emscripten/tools/exec_llvm.py +50 -0
  1033. data/modules/emscripten/tools/file2json.py +49 -0
  1034. data/modules/emscripten/tools/file_packager.py +649 -0
  1035. data/modules/emscripten/tools/find_bigfuncs.py +23 -0
  1036. data/modules/emscripten/tools/find_bigis.py +18 -0
  1037. data/modules/emscripten/tools/fix_closure.py +88 -0
  1038. data/modules/emscripten/tools/ie7_fix.py +14 -0
  1039. data/modules/emscripten/tools/js-optimizer.js +3440 -0
  1040. data/modules/emscripten/tools/js_optimizer.py +341 -0
  1041. data/modules/emscripten/tools/js_optimizer.pyc +0 -0
  1042. data/modules/emscripten/tools/jsrun.py +27 -0
  1043. data/modules/emscripten/tools/jsrun.pyc +0 -0
  1044. data/modules/emscripten/tools/ll-strip.py +56 -0
  1045. data/modules/emscripten/tools/make_file.py +19 -0
  1046. data/modules/emscripten/tools/make_minigzip.py +13 -0
  1047. data/modules/emscripten/tools/namespacer.py +95 -0
  1048. data/modules/emscripten/tools/nativize_llvm.py +34 -0
  1049. data/modules/emscripten/tools/node_modules/source-map/CHANGELOG.md +58 -0
  1050. data/modules/emscripten/tools/node_modules/source-map/LICENSE +28 -0
  1051. data/modules/emscripten/tools/node_modules/source-map/Makefile.dryice.js +166 -0
  1052. data/modules/emscripten/tools/node_modules/source-map/README.md +347 -0
  1053. data/modules/emscripten/tools/node_modules/source-map/build/assert-shim.js +56 -0
  1054. data/modules/emscripten/tools/node_modules/source-map/build/mini-require.js +152 -0
  1055. data/modules/emscripten/tools/node_modules/source-map/build/prefix-source-map.jsm +20 -0
  1056. data/modules/emscripten/tools/node_modules/source-map/build/prefix-utils.jsm +18 -0
  1057. data/modules/emscripten/tools/node_modules/source-map/build/suffix-browser.js +8 -0
  1058. data/modules/emscripten/tools/node_modules/source-map/build/suffix-source-map.jsm +6 -0
  1059. data/modules/emscripten/tools/node_modules/source-map/build/suffix-utils.jsm +21 -0
  1060. data/modules/emscripten/tools/node_modules/source-map/build/test-prefix.js +8 -0
  1061. data/modules/emscripten/tools/node_modules/source-map/build/test-suffix.js +3 -0
  1062. data/modules/emscripten/tools/node_modules/source-map/lib/source-map/array-set.js +96 -0
  1063. data/modules/emscripten/tools/node_modules/source-map/lib/source-map/base64-vlq.js +144 -0
  1064. data/modules/emscripten/tools/node_modules/source-map/lib/source-map/base64.js +42 -0
  1065. data/modules/emscripten/tools/node_modules/source-map/lib/source-map/binary-search.js +81 -0
  1066. data/modules/emscripten/tools/node_modules/source-map/lib/source-map/source-map-consumer.js +430 -0
  1067. data/modules/emscripten/tools/node_modules/source-map/lib/source-map/source-map-generator.js +381 -0
  1068. data/modules/emscripten/tools/node_modules/source-map/lib/source-map/source-node.js +353 -0
  1069. data/modules/emscripten/tools/node_modules/source-map/lib/source-map/util.js +117 -0
  1070. data/modules/emscripten/tools/node_modules/source-map/lib/source-map.js +8 -0
  1071. data/modules/emscripten/tools/node_modules/source-map/node_modules/amdefine/LICENSE +58 -0
  1072. data/modules/emscripten/tools/node_modules/source-map/node_modules/amdefine/README.md +119 -0
  1073. data/modules/emscripten/tools/node_modules/source-map/node_modules/amdefine/amdefine.js +299 -0
  1074. data/modules/emscripten/tools/node_modules/source-map/node_modules/amdefine/package.json +33 -0
  1075. data/modules/emscripten/tools/node_modules/source-map/package.json +74 -0
  1076. data/modules/emscripten/tools/node_modules/source-map/test/run-tests.js +73 -0
  1077. data/modules/emscripten/tools/node_modules/source-map/test/source-map/test-api.js +26 -0
  1078. data/modules/emscripten/tools/node_modules/source-map/test/source-map/test-array-set.js +71 -0
  1079. data/modules/emscripten/tools/node_modules/source-map/test/source-map/test-base64-vlq.js +24 -0
  1080. data/modules/emscripten/tools/node_modules/source-map/test/source-map/test-base64.js +35 -0
  1081. data/modules/emscripten/tools/node_modules/source-map/test/source-map/test-binary-search.js +54 -0
  1082. data/modules/emscripten/tools/node_modules/source-map/test/source-map/test-dog-fooding.js +72 -0
  1083. data/modules/emscripten/tools/node_modules/source-map/test/source-map/test-source-map-consumer.js +306 -0
  1084. data/modules/emscripten/tools/node_modules/source-map/test/source-map/test-source-map-generator.js +391 -0
  1085. data/modules/emscripten/tools/node_modules/source-map/test/source-map/test-source-node.js +282 -0
  1086. data/modules/emscripten/tools/node_modules/source-map/test/source-map/util.js +152 -0
  1087. data/modules/emscripten/tools/reproduceriter.js +216 -0
  1088. data/modules/emscripten/tools/reproduceriter.py +160 -0
  1089. data/modules/emscripten/tools/response_file.py +28 -0
  1090. data/modules/emscripten/tools/response_file.pyc +0 -0
  1091. data/modules/emscripten/tools/scan_js.py +20 -0
  1092. data/modules/emscripten/tools/scan_ll.py +18 -0
  1093. data/modules/emscripten/tools/scons/site_scons/site_tools/emscripten/__init__.py +3 -0
  1094. data/modules/emscripten/tools/scons/site_scons/site_tools/emscripten/emscripten.py +46 -0
  1095. data/modules/emscripten/tools/settings_template_readonly.py +47 -0
  1096. data/modules/emscripten/tools/shared.py +1437 -0
  1097. data/modules/emscripten/tools/shared.pyc +0 -0
  1098. data/modules/emscripten/tools/source-maps/sourcemap2json.js +15 -0
  1099. data/modules/emscripten/tools/source-maps/sourcemapper.js +177 -0
  1100. data/modules/emscripten/tools/split.py +97 -0
  1101. data/modules/emscripten/tools/tempfiles.py +40 -0
  1102. data/modules/emscripten/tools/tempfiles.pyc +0 -0
  1103. data/modules/emscripten/tools/test-js-optimizer-asm-last-output.js +75 -0
  1104. data/modules/emscripten/tools/test-js-optimizer-asm-last.js +91 -0
  1105. data/modules/emscripten/tools/test-js-optimizer-asm-outline-output.js +570 -0
  1106. data/modules/emscripten/tools/test-js-optimizer-asm-outline.js +606 -0
  1107. data/modules/emscripten/tools/test-js-optimizer-asm-pre-output.js +540 -0
  1108. data/modules/emscripten/tools/test-js-optimizer-asm-pre.js +550 -0
  1109. data/modules/emscripten/tools/test-js-optimizer-asm-regs-min-output.js +36 -0
  1110. data/modules/emscripten/tools/test-js-optimizer-asm-regs-min.js +37 -0
  1111. data/modules/emscripten/tools/test-js-optimizer-asm-regs-output.js +106 -0
  1112. data/modules/emscripten/tools/test-js-optimizer-asm-regs.js +110 -0
  1113. data/modules/emscripten/tools/test-js-optimizer-asm-relocate-output.js +9 -0
  1114. data/modules/emscripten/tools/test-js-optimizer-asm-relocate.js +12 -0
  1115. data/modules/emscripten/tools/test-js-optimizer-output.js +291 -0
  1116. data/modules/emscripten/tools/test-js-optimizer-regs-output.js +232 -0
  1117. data/modules/emscripten/tools/test-js-optimizer-regs.js +237 -0
  1118. data/modules/emscripten/tools/test-js-optimizer-t2-output.js +91 -0
  1119. data/modules/emscripten/tools/test-js-optimizer-t2.js +92 -0
  1120. data/modules/emscripten/tools/test-js-optimizer-t2c-output.js +17 -0
  1121. data/modules/emscripten/tools/test-js-optimizer-t2c.js +18 -0
  1122. data/modules/emscripten/tools/test-js-optimizer-t3-output.js +49 -0
  1123. data/modules/emscripten/tools/test-js-optimizer-t3.js +50 -0
  1124. data/modules/emscripten/tools/test-js-optimizer.js +401 -0
  1125. data/modules/mruby/AUTHORS +18 -0
  1126. data/modules/mruby/CONTRIBUTING.md +65 -0
  1127. data/modules/mruby/ChangeLog +15 -0
  1128. data/modules/mruby/INSTALL +29 -0
  1129. data/modules/mruby/LEGAL +6 -0
  1130. data/modules/mruby/MITL +20 -0
  1131. data/modules/mruby/Makefile +18 -0
  1132. data/modules/mruby/NEWS +13 -0
  1133. data/modules/mruby/README.md +116 -0
  1134. data/modules/mruby/Rakefile +114 -0
  1135. data/modules/mruby/TODO +11 -0
  1136. data/modules/mruby/benchmark/ao-render.rb +315 -0
  1137. data/modules/mruby/benchmark/bm_so_lists.rb +47 -0
  1138. data/modules/mruby/benchmark/fib39.rb +8 -0
  1139. data/modules/mruby/build_config.rb +88 -0
  1140. data/modules/mruby/doc/compile/README.md +376 -0
  1141. data/modules/mruby/doc/mrbgems/README.md +254 -0
  1142. data/modules/mruby/examples/mrbgems/c_and_ruby_extension_example/README.md +4 -0
  1143. data/modules/mruby/examples/mrbgems/c_and_ruby_extension_example/mrbgem.rake +23 -0
  1144. data/modules/mruby/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb +5 -0
  1145. data/modules/mruby/examples/mrbgems/c_and_ruby_extension_example/src/example.c +20 -0
  1146. data/modules/mruby/examples/mrbgems/c_and_ruby_extension_example/test/example.rb +7 -0
  1147. data/modules/mruby/examples/mrbgems/c_extension_example/README.md +4 -0
  1148. data/modules/mruby/examples/mrbgems/c_extension_example/mrbgem.rake +23 -0
  1149. data/modules/mruby/examples/mrbgems/c_extension_example/src/example.c +20 -0
  1150. data/modules/mruby/examples/mrbgems/c_extension_example/test/example.c +7 -0
  1151. data/modules/mruby/examples/mrbgems/c_extension_example/test/example.rb +3 -0
  1152. data/modules/mruby/examples/mrbgems/ruby_extension_example/README.md +4 -0
  1153. data/modules/mruby/examples/mrbgems/ruby_extension_example/mrbgem.rake +23 -0
  1154. data/modules/mruby/examples/mrbgems/ruby_extension_example/mrblib/example.rb +5 -0
  1155. data/modules/mruby/examples/mrbgems/ruby_extension_example/test/example.rb +3 -0
  1156. data/modules/mruby/examples/targets/ArduinoDue.rb +65 -0
  1157. data/modules/mruby/examples/targets/chipKitMax32.rb +68 -0
  1158. data/modules/mruby/include/mrbconf.h +87 -0
  1159. data/modules/mruby/include/mruby/array.h +63 -0
  1160. data/modules/mruby/include/mruby/class.h +75 -0
  1161. data/modules/mruby/include/mruby/compile.h +176 -0
  1162. data/modules/mruby/include/mruby/data.h +53 -0
  1163. data/modules/mruby/include/mruby/dump.h +151 -0
  1164. data/modules/mruby/include/mruby/gc.h +17 -0
  1165. data/modules/mruby/include/mruby/hash.h +54 -0
  1166. data/modules/mruby/include/mruby/irep.h +40 -0
  1167. data/modules/mruby/include/mruby/khash.h +257 -0
  1168. data/modules/mruby/include/mruby/numeric.h +32 -0
  1169. data/modules/mruby/include/mruby/proc.h +62 -0
  1170. data/modules/mruby/include/mruby/range.h +35 -0
  1171. data/modules/mruby/include/mruby/string.h +78 -0
  1172. data/modules/mruby/include/mruby/value.h +483 -0
  1173. data/modules/mruby/include/mruby/variable.h +78 -0
  1174. data/modules/mruby/include/mruby.h +388 -0
  1175. data/modules/mruby/minirake +477 -0
  1176. data/modules/mruby/mrbgems/default.gembox +61 -0
  1177. data/modules/mruby/mrbgems/full-core.gembox +9 -0
  1178. data/modules/mruby/mrbgems/mruby-array-ext/mrbgem.rake +4 -0
  1179. data/modules/mruby/mrbgems/mruby-array-ext/mrblib/array.rb +204 -0
  1180. data/modules/mruby/mrbgems/mruby-array-ext/src/array.c +140 -0
  1181. data/modules/mruby/mrbgems/mruby-array-ext/test/array.rb +109 -0
  1182. data/modules/mruby/mrbgems/mruby-bin-mirb/mrbgem.rake +5 -0
  1183. data/modules/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +365 -0
  1184. data/modules/mruby/mrbgems/mruby-bin-mruby/mrbgem.rake +5 -0
  1185. data/modules/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +243 -0
  1186. data/modules/mruby/mrbgems/mruby-enum-ext/mrbgem.rake +4 -0
  1187. data/modules/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb +164 -0
  1188. data/modules/mruby/mrbgems/mruby-enum-ext/test/enum.rb +44 -0
  1189. data/modules/mruby/mrbgems/mruby-eval/mrbgem.rake +4 -0
  1190. data/modules/mruby/mrbgems/mruby-eval/src/eval.c +23 -0
  1191. data/modules/mruby/mrbgems/mruby-fiber/mrbgem.rake +4 -0
  1192. data/modules/mruby/mrbgems/mruby-fiber/src/fiber.c +251 -0
  1193. data/modules/mruby/mrbgems/mruby-fiber/test/fiber.rb +64 -0
  1194. data/modules/mruby/mrbgems/mruby-hash-ext/mrbgem.rake +4 -0
  1195. data/modules/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb +13 -0
  1196. data/modules/mruby/mrbgems/mruby-hash-ext/src/hash-ext.c +62 -0
  1197. data/modules/mruby/mrbgems/mruby-hash-ext/test/hash.rb +26 -0
  1198. data/modules/mruby/mrbgems/mruby-math/mrbgem.rake +4 -0
  1199. data/modules/mruby/mrbgems/mruby-math/src/math.c +685 -0
  1200. data/modules/mruby/mrbgems/mruby-math/test/math.rb +136 -0
  1201. data/modules/mruby/mrbgems/mruby-numeric-ext/mrbgem.rake +4 -0
  1202. data/modules/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c +31 -0
  1203. data/modules/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb +10 -0
  1204. data/modules/mruby/mrbgems/mruby-object-ext/mrbgem.rake +4 -0
  1205. data/modules/mruby/mrbgems/mruby-object-ext/src/object.c +108 -0
  1206. data/modules/mruby/mrbgems/mruby-object-ext/test/nil.rb +11 -0
  1207. data/modules/mruby/mrbgems/mruby-object-ext/test/object.rb +9 -0
  1208. data/modules/mruby/mrbgems/mruby-objectspace/mrbgem.rake +4 -0
  1209. data/modules/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c +117 -0
  1210. data/modules/mruby/mrbgems/mruby-objectspace/test/objectspace.rb +38 -0
  1211. data/modules/mruby/mrbgems/mruby-print/mrbgem.rake +4 -0
  1212. data/modules/mruby/mrbgems/mruby-print/mrblib/print.rb +64 -0
  1213. data/modules/mruby/mrbgems/mruby-print/src/print.c +44 -0
  1214. data/modules/mruby/mrbgems/mruby-proc-ext/mrbgem.rake +4 -0
  1215. data/modules/mruby/mrbgems/mruby-proc-ext/mrblib/proc.rb +40 -0
  1216. data/modules/mruby/mrbgems/mruby-proc-ext/src/proc.c +97 -0
  1217. data/modules/mruby/mrbgems/mruby-proc-ext/test/proc.rb +41 -0
  1218. data/modules/mruby/mrbgems/mruby-random/mrbgem.rake +4 -0
  1219. data/modules/mruby/mrbgems/mruby-random/src/mt19937ar.c +193 -0
  1220. data/modules/mruby/mrbgems/mruby-random/src/mt19937ar.h +48 -0
  1221. data/modules/mruby/mrbgems/mruby-random/src/random.c +231 -0
  1222. data/modules/mruby/mrbgems/mruby-random/src/random.h +12 -0
  1223. data/modules/mruby/mrbgems/mruby-random/test/random.rb +32 -0
  1224. data/modules/mruby/mrbgems/mruby-range-ext/mrbgem.rake +4 -0
  1225. data/modules/mruby/mrbgems/mruby-range-ext/src/range.c +141 -0
  1226. data/modules/mruby/mrbgems/mruby-range-ext/test/range.rb +20 -0
  1227. data/modules/mruby/mrbgems/mruby-sprintf/mrbgem.rake +4 -0
  1228. data/modules/mruby/mrbgems/mruby-sprintf/src/kernel.c +30 -0
  1229. data/modules/mruby/mrbgems/mruby-sprintf/src/sprintf.c +1102 -0
  1230. data/modules/mruby/mrbgems/mruby-sprintf/test/sprintf.rb +3 -0
  1231. data/modules/mruby/mrbgems/mruby-string-ext/mrbgem.rake +4 -0
  1232. data/modules/mruby/mrbgems/mruby-string-ext/mrblib/string.rb +52 -0
  1233. data/modules/mruby/mrbgems/mruby-string-ext/src/string.c +175 -0
  1234. data/modules/mruby/mrbgems/mruby-string-ext/test/string.rb +112 -0
  1235. data/modules/mruby/mrbgems/mruby-struct/mrbgem.rake +4 -0
  1236. data/modules/mruby/mrbgems/mruby-struct/mrblib/struct.rb +50 -0
  1237. data/modules/mruby/mrbgems/mruby-struct/src/struct.c +818 -0
  1238. data/modules/mruby/mrbgems/mruby-struct/test/struct.rb +77 -0
  1239. data/modules/mruby/mrbgems/mruby-symbol-ext/mrbgem.rake +4 -0
  1240. data/modules/mruby/mrbgems/mruby-symbol-ext/mrblib/symbol.rb +9 -0
  1241. data/modules/mruby/mrbgems/mruby-symbol-ext/src/symbol.c +55 -0
  1242. data/modules/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb +12 -0
  1243. data/modules/mruby/mrbgems/mruby-time/mrbgem.rake +4 -0
  1244. data/modules/mruby/mrbgems/mruby-time/src/time.c +749 -0
  1245. data/modules/mruby/mrbgems/mruby-time/test/time.rb +201 -0
  1246. data/modules/mruby/mrbgems/mruby-toplevel-ext/mrbgem.rake +4 -0
  1247. data/modules/mruby/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb +11 -0
  1248. data/modules/mruby/mrbgems/mruby-toplevel-ext/test/toplevel.rb +24 -0
  1249. data/modules/mruby/mrblib/array.rb +111 -0
  1250. data/modules/mruby/mrblib/class.rb +26 -0
  1251. data/modules/mruby/mrblib/compar.rb +104 -0
  1252. data/modules/mruby/mrblib/enum.rb +398 -0
  1253. data/modules/mruby/mrblib/error.rb +66 -0
  1254. data/modules/mruby/mrblib/hash.rb +193 -0
  1255. data/modules/mruby/mrblib/init_mrblib.c +14 -0
  1256. data/modules/mruby/mrblib/kernel.rb +46 -0
  1257. data/modules/mruby/mrblib/mrblib.rake +18 -0
  1258. data/modules/mruby/mrblib/numeric.rb +101 -0
  1259. data/modules/mruby/mrblib/print.rb +18 -0
  1260. data/modules/mruby/mrblib/range.rb +40 -0
  1261. data/modules/mruby/mrblib/string.rb +145 -0
  1262. data/modules/mruby/src/array.c +1150 -0
  1263. data/modules/mruby/src/backtrace.c +73 -0
  1264. data/modules/mruby/src/class.c +1942 -0
  1265. data/modules/mruby/src/codegen.c +2864 -0
  1266. data/modules/mruby/src/compar.c +13 -0
  1267. data/modules/mruby/src/crc.c +38 -0
  1268. data/modules/mruby/src/dump.c +542 -0
  1269. data/modules/mruby/src/enum.c +14 -0
  1270. data/modules/mruby/src/error.c +454 -0
  1271. data/modules/mruby/src/error.h +18 -0
  1272. data/modules/mruby/src/etc.c +204 -0
  1273. data/modules/mruby/src/gc.c +1542 -0
  1274. data/modules/mruby/src/hash.c +1261 -0
  1275. data/modules/mruby/src/init.c +62 -0
  1276. data/modules/mruby/src/kernel.c +1105 -0
  1277. data/modules/mruby/src/keywords +50 -0
  1278. data/modules/mruby/src/lex.def +212 -0
  1279. data/modules/mruby/src/load.c +629 -0
  1280. data/modules/mruby/src/mruby_core.rake +28 -0
  1281. data/modules/mruby/src/node.h +117 -0
  1282. data/modules/mruby/src/numeric.c +1418 -0
  1283. data/modules/mruby/src/object.c +593 -0
  1284. data/modules/mruby/src/opcode.h +160 -0
  1285. data/modules/mruby/src/parse.y +6050 -0
  1286. data/modules/mruby/src/pool.c +190 -0
  1287. data/modules/mruby/src/print.c +71 -0
  1288. data/modules/mruby/src/proc.c +209 -0
  1289. data/modules/mruby/src/range.c +442 -0
  1290. data/modules/mruby/src/re.h +13 -0
  1291. data/modules/mruby/src/state.c +200 -0
  1292. data/modules/mruby/src/string.c +2580 -0
  1293. data/modules/mruby/src/symbol.c +456 -0
  1294. data/modules/mruby/src/value_array.h +27 -0
  1295. data/modules/mruby/src/variable.c +1147 -0
  1296. data/modules/mruby/src/vm.c +2129 -0
  1297. data/modules/mruby/tasks/libmruby.rake +18 -0
  1298. data/modules/mruby/tasks/mrbgem_spec.rake +297 -0
  1299. data/modules/mruby/tasks/mrbgems.rake +85 -0
  1300. data/modules/mruby/tasks/mrbgems_test.rake +88 -0
  1301. data/modules/mruby/tasks/mruby_build.rake +211 -0
  1302. data/modules/mruby/tasks/mruby_build_commands.rake +287 -0
  1303. data/modules/mruby/tasks/mruby_build_gem.rake +67 -0
  1304. data/modules/mruby/tasks/ruby_ext.rake +70 -0
  1305. data/modules/mruby/tasks/toolchains/androideabi.rake +126 -0
  1306. data/modules/mruby/tasks/toolchains/clang.rake +8 -0
  1307. data/modules/mruby/tasks/toolchains/gcc.rake +21 -0
  1308. data/modules/mruby/tasks/toolchains/vs2010.rake +3 -0
  1309. data/modules/mruby/tasks/toolchains/vs2012.rake +44 -0
  1310. data/modules/mruby/test/README.md +7 -0
  1311. data/modules/mruby/test/assert.rb +238 -0
  1312. data/modules/mruby/test/driver.c +118 -0
  1313. data/modules/mruby/test/init_mrbtest.c +24 -0
  1314. data/modules/mruby/test/mrbtest.rake +47 -0
  1315. data/modules/mruby/test/report.rb +4 -0
  1316. data/modules/mruby/test/t/argumenterror.rb +21 -0
  1317. data/modules/mruby/test/t/array.rb +309 -0
  1318. data/modules/mruby/test/t/basicobject.rb +11 -0
  1319. data/modules/mruby/test/t/bs_block.rb +489 -0
  1320. data/modules/mruby/test/t/bs_literal.rb +38 -0
  1321. data/modules/mruby/test/t/class.rb +219 -0
  1322. data/modules/mruby/test/t/comparable.rb +72 -0
  1323. data/modules/mruby/test/t/enumerable.rb +108 -0
  1324. data/modules/mruby/test/t/exception.rb +337 -0
  1325. data/modules/mruby/test/t/false.rb +33 -0
  1326. data/modules/mruby/test/t/float.rb +145 -0
  1327. data/modules/mruby/test/t/gc.rb +45 -0
  1328. data/modules/mruby/test/t/hash.rb +310 -0
  1329. data/modules/mruby/test/t/indexerror.rb +10 -0
  1330. data/modules/mruby/test/t/integer.rb +222 -0
  1331. data/modules/mruby/test/t/kernel.rb +425 -0
  1332. data/modules/mruby/test/t/literals.rb +287 -0
  1333. data/modules/mruby/test/t/localjumperror.rb +13 -0
  1334. data/modules/mruby/test/t/methods.rb +109 -0
  1335. data/modules/mruby/test/t/module.rb +344 -0
  1336. data/modules/mruby/test/t/nameerror.rb +32 -0
  1337. data/modules/mruby/test/t/nil.rb +29 -0
  1338. data/modules/mruby/test/t/nomethoderror.rb +13 -0
  1339. data/modules/mruby/test/t/numeric.rb +29 -0
  1340. data/modules/mruby/test/t/object.rb +11 -0
  1341. data/modules/mruby/test/t/proc.rb +56 -0
  1342. data/modules/mruby/test/t/range.rb +82 -0
  1343. data/modules/mruby/test/t/rangeerror.rb +10 -0
  1344. data/modules/mruby/test/t/regexperror.rb +4 -0
  1345. data/modules/mruby/test/t/runtimeerror.rb +6 -0
  1346. data/modules/mruby/test/t/standarderror.rb +10 -0
  1347. data/modules/mruby/test/t/string.rb +483 -0
  1348. data/modules/mruby/test/t/symbol.rb +27 -0
  1349. data/modules/mruby/test/t/syntax.rb +67 -0
  1350. data/modules/mruby/test/t/true.rb +33 -0
  1351. data/modules/mruby/test/t/typeerror.rb +11 -0
  1352. data/modules/mruby/tools/mrbc/mrbc.c +318 -0
  1353. data/modules/mruby/tools/mrbc/mrbc.rake +14 -0
  1354. data/modules/mruby/travis_config.rb +6 -0
  1355. data/modules/mrubymix/LICENSE +21 -0
  1356. data/modules/mrubymix/README.md +6 -0
  1357. data/modules/mrubymix/bin/mrubymix +29 -0
  1358. data/modules/mrubymix/lib/mrubymix.rb +93 -0
  1359. data/modules/mrubymix/mrubymix.gemspec +13 -0
  1360. data/scripts/gen_gems_config.rb +185 -0
  1361. data/scripts/gen_post.rb +104 -0
  1362. data/templates/minimal/Rakefile +36 -0
  1363. data/templates/minimal/app/app.rb +3 -0
  1364. metadata +1408 -0
@@ -0,0 +1,3440 @@
1
+ //==============================================================================
2
+ // Optimizer tool. This is meant to be run after the emscripten compiler has
3
+ // finished generating code. These optimizations are done on the generated
4
+ // code to further improve it. Some of the modifications also work in
5
+ // conjunction with closure compiler.
6
+ //
7
+ // TODO: Optimize traverse to modify a node we want to replace, in-place,
8
+ // instead of returning it to the previous call frame where we check?
9
+ // TODO: Share EMPTY_NODE instead of emptyNode that constructs?
10
+ //==============================================================================
11
+
12
+ // *** Environment setup code ***
13
+ var arguments_ = [];
14
+ var debug = false;
15
+
16
+ var ENVIRONMENT_IS_NODE = typeof process === 'object';
17
+ var ENVIRONMENT_IS_WEB = typeof window === 'object';
18
+ var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
19
+ var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
20
+
21
+ if (ENVIRONMENT_IS_NODE) {
22
+ // Expose functionality in the same simple way that the shells work
23
+ // Note that we pollute the global namespace here, otherwise we break in node
24
+ print = function(x) {
25
+ process['stdout'].write(x + '\n');
26
+ };
27
+ printErr = function(x) {
28
+ process['stderr'].write(x + '\n');
29
+ };
30
+
31
+ var nodeFS = require('fs');
32
+ var nodePath = require('path');
33
+
34
+ if (!nodeFS.existsSync) {
35
+ nodeFS.existsSync = function(path) {
36
+ try {
37
+ return !!nodeFS.readFileSync(path);
38
+ } catch(e) {
39
+ return false;
40
+ }
41
+ }
42
+ }
43
+
44
+ function find(filename) {
45
+ var prefixes = [nodePath.join(__dirname, '..', 'src'), process.cwd()];
46
+ for (var i = 0; i < prefixes.length; ++i) {
47
+ var combined = nodePath.join(prefixes[i], filename);
48
+ if (nodeFS.existsSync(combined)) {
49
+ return combined;
50
+ }
51
+ }
52
+ return filename;
53
+ }
54
+
55
+ read = function(filename) {
56
+ var absolute = find(filename);
57
+ return nodeFS['readFileSync'](absolute).toString();
58
+ };
59
+
60
+ load = function(f) {
61
+ globalEval(read(f));
62
+ };
63
+
64
+ arguments_ = process['argv'].slice(2);
65
+
66
+ } else if (ENVIRONMENT_IS_SHELL) {
67
+ // Polyfill over SpiderMonkey/V8 differences
68
+ if (!this['read']) {
69
+ this['read'] = function(f) { snarf(f) };
70
+ }
71
+
72
+ if (typeof scriptArgs != 'undefined') {
73
+ arguments_ = scriptArgs;
74
+ } else if (typeof arguments != 'undefined') {
75
+ arguments_ = arguments;
76
+ }
77
+
78
+ } else if (ENVIRONMENT_IS_WEB) {
79
+ this['print'] = printErr = function(x) {
80
+ console.log(x);
81
+ };
82
+
83
+ this['read'] = function(url) {
84
+ var xhr = new XMLHttpRequest();
85
+ xhr.open('GET', url, false);
86
+ xhr.send(null);
87
+ return xhr.responseText;
88
+ };
89
+
90
+ if (this['arguments']) {
91
+ arguments_ = arguments;
92
+ }
93
+ } else if (ENVIRONMENT_IS_WORKER) {
94
+ // We can do very little here...
95
+
96
+ this['load'] = importScripts;
97
+
98
+ } else {
99
+ throw 'Unknown runtime environment. Where are we?';
100
+ }
101
+
102
+ function globalEval(x) {
103
+ eval.call(null, x);
104
+ }
105
+
106
+ if (typeof load === 'undefined' && typeof read != 'undefined') {
107
+ this['load'] = function(f) {
108
+ globalEval(read(f));
109
+ };
110
+ }
111
+
112
+ if (typeof printErr === 'undefined') {
113
+ this['printErr'] = function(){};
114
+ }
115
+
116
+ if (typeof print === 'undefined') {
117
+ this['print'] = printErr;
118
+ }
119
+ // *** Environment setup code ***
120
+
121
+ var uglify = require('../tools/eliminator/node_modules/uglify-js');
122
+ var fs = require('fs');
123
+ var path = require('path');
124
+
125
+ // Load some modules
126
+
127
+ load('utility.js');
128
+
129
+ // Utilities
130
+
131
+ var FUNCTION = set('defun', 'function');
132
+ var LOOP = set('do', 'while', 'for');
133
+ var LOOP_FLOW = set('break', 'continue');
134
+ var ASSIGN_OR_ALTER = set('assign', 'unary-postfix', 'unary-prefix');
135
+ var CONTROL_FLOW = set('do', 'while', 'for', 'if', 'switch');
136
+ var NAME_OR_NUM = set('name', 'num');
137
+ var ASSOCIATIVE_BINARIES = set('+', '*', '|', '&', '^');
138
+
139
+ var BREAK_CAPTURERS = set('do', 'while', 'for', 'switch');
140
+ var CONTINUE_CAPTURERS = LOOP;
141
+
142
+ var NULL_NODE = ['name', 'null'];
143
+ var UNDEFINED_NODE = ['unary-prefix', 'void', ['num', 0]];
144
+ var TRUE_NODE = ['unary-prefix', '!', ['num', 0]];
145
+ var FALSE_NODE = ['unary-prefix', '!', ['num', 1]];
146
+
147
+ var GENERATED_FUNCTIONS_MARKER = '// EMSCRIPTEN_GENERATED_FUNCTIONS';
148
+ var generatedFunctions = false; // whether we have received only generated functions
149
+
150
+ var extraInfo = null;
151
+
152
+ function srcToAst(src) {
153
+ return uglify.parser.parse(src, false, debug);
154
+ }
155
+
156
+ function astToSrc(ast, minifyWhitespace) {
157
+ return uglify.uglify.gen_code(ast, {
158
+ debug: debug,
159
+ ascii_only: true,
160
+ beautify: !minifyWhitespace,
161
+ indent_level: 1
162
+ });
163
+ }
164
+
165
+ // Traverses the children of a node. If the traverse function returns an object,
166
+ // replaces the child. If it returns true, stop the traversal and return true.
167
+ function traverseChildren(node, traverse, pre, post, stack) {
168
+ for (var i = 0; i < node.length; i++) {
169
+ var subnode = node[i];
170
+ if (Array.isArray(subnode)) {
171
+ var subresult = traverse(subnode, pre, post, stack);
172
+ if (subresult === true) return true;
173
+ if (subresult !== null && typeof subresult === 'object') node[i] = subresult;
174
+ }
175
+ }
176
+ }
177
+
178
+ // Traverses a JavaScript syntax tree rooted at the given node calling the given
179
+ // callback for each node.
180
+ // @arg node: The root of the AST.
181
+ // @arg pre: The pre to call for each node. This will be called with
182
+ // the node as the first argument and its type as the second. If true is
183
+ // returned, the traversal is stopped. If an object is returned,
184
+ // it replaces the passed node in the tree. If null is returned, we stop
185
+ // traversing the subelements (but continue otherwise).
186
+ // @arg post: A callback to call after traversing all children.
187
+ // @arg stack: If true, a stack will be implemented: If pre does not push on
188
+ // the stack, we push a 0. We pop when we leave the node. The
189
+ // stack is passed as a third parameter to the callbacks.
190
+ // @returns: If the root node was replaced, the new root node. If the traversal
191
+ // was stopped, true. Otherwise undefined.
192
+ function traverse(node, pre, post, stack) {
193
+ var type = node[0], result, len;
194
+ var relevant = typeof type === 'string';
195
+ if (relevant) {
196
+ if (stack) len = stack.length;
197
+ var result = pre(node, type, stack);
198
+ if (result === true) return true;
199
+ if (result && result !== null) node = result; // Continue processing on this node
200
+ if (stack && len === stack.length) stack.push(0);
201
+ }
202
+ if (result !== null) {
203
+ if (traverseChildren(node, traverse, pre, post, stack) === true) return true;
204
+ }
205
+ if (relevant) {
206
+ if (post) {
207
+ var postResult = post(node, type, stack);
208
+ result = result || postResult;
209
+ }
210
+ if (stack) stack.pop();
211
+ }
212
+ return result;
213
+ }
214
+
215
+ // Only walk through the generated functions
216
+ function traverseGenerated(ast, pre, post, stack) {
217
+ assert(generatedFunctions);
218
+ traverse(ast, function(node) {
219
+ if (node[0] === 'defun') {
220
+ traverse(node, pre, post, stack);
221
+ return null;
222
+ }
223
+ });
224
+ }
225
+
226
+ function traverseGeneratedFunctions(ast, callback) {
227
+ assert(generatedFunctions);
228
+ if (ast[0] === 'toplevel') {
229
+ var stats = ast[1];
230
+ for (var i = 0; i < stats.length; i++) {
231
+ var curr = stats[i];
232
+ if (curr[0] === 'defun') callback(curr);
233
+ }
234
+ } else if (ast[0] === 'defun') {
235
+ callback(ast);
236
+ }
237
+ }
238
+
239
+ // Walk the ast in a simple way, with an understanding of which JS variables are defined)
240
+ function traverseWithVariables(ast, callback) {
241
+ traverse(ast, function(node, type, stack) {
242
+ if (type in FUNCTION) {
243
+ stack.push({ type: 'function', vars: node[2] });
244
+ } else if (type === 'var') {
245
+ // Find our function, add our vars
246
+ var func = stack[stack.length-1];
247
+ if (func) {
248
+ func.vars = func.vars.concat(node[1].map(function(varItem) { return varItem[0] }));
249
+ }
250
+ }
251
+ }, function(node, type, stack) {
252
+ if (type === 'toplevel' || type in FUNCTION) {
253
+ // We know all of the variables that are seen here, proceed to do relevant replacements
254
+ var allVars = stack.map(function(item) { return item ? item.vars : [] }).reduce(concatenator, []); // FIXME dictionary for speed?
255
+ traverse(node, function(node2, type2, stack2) {
256
+ // Be careful not to look into our inner functions. They have already been processed.
257
+ if (sum(stack2) > 1 || (type === 'toplevel' && sum(stack2) === 1)) return;
258
+ if (type2 in FUNCTION) stack2.push(1);
259
+ return callback(node2, type2, allVars);
260
+ }, null, []);
261
+ }
262
+ }, []);
263
+ }
264
+
265
+ function emptyNode() { // XXX do we need to create new nodes here? can't we reuse?
266
+ return ['toplevel', []]
267
+ }
268
+
269
+ function isEmptyNode(node) {
270
+ return node.length === 2 && node[0] === 'toplevel' && node[1].length === 0;
271
+ }
272
+
273
+ // Passes
274
+
275
+ // Dump the AST. Useful for debugging. For example,
276
+ // node tools/js-optimizer.js ABSOLUTE_PATH_TO_FILE dumpAst
277
+ function dumpAst(ast) {
278
+ printErr(JSON.stringify(ast, null, ' '));
279
+ }
280
+
281
+ function dumpSrc(ast) {
282
+ printErr(astToSrc(ast));
283
+ }
284
+
285
+ // Undos closure's creation of global variables with values true, false,
286
+ // undefined, null. These cut down on size, but do not affect gzip size
287
+ // and make JS engine's lives slightly harder (?)
288
+ function unGlobalize(ast) {
289
+
290
+ throw 'this is deprecated!'; // and does not work with parallel compilation
291
+
292
+ assert(ast[0] === 'toplevel');
293
+ var values = {};
294
+ // Find global renamings of the relevant values
295
+ ast[1].forEach(function(node, i) {
296
+ if (node[0] != 'var') return;
297
+ node[1] = node[1].filter(function(varItem, j) {
298
+ var ident = varItem[0];
299
+ var value = varItem[1];
300
+ if (!value) return true;
301
+ var possible = false;
302
+ if (jsonCompare(value, NULL_NODE) ||
303
+ jsonCompare(value, UNDEFINED_NODE) ||
304
+ jsonCompare(value, TRUE_NODE) ||
305
+ jsonCompare(value, FALSE_NODE)) {
306
+ possible = true;
307
+ }
308
+ if (!possible) return true;
309
+ // Make sure there are no assignments to this variable. (This isn't fast, we traverse many times..)
310
+ ast[1][i][1][j] = emptyNode();
311
+ var assigned = false;
312
+ traverseWithVariables(ast, function(node, type, allVars) {
313
+ if (type === 'assign' && node[2][0] === 'name' && node[2][1] === ident) assigned = true;
314
+ });
315
+ ast[1][i][1][j] = [ident, value];
316
+ if (!assigned) {
317
+ values[ident] = value;
318
+ return false;
319
+ }
320
+ return true;
321
+ });
322
+
323
+ if (node[1].length === 0) {
324
+ ast[1][i] = emptyNode();
325
+ }
326
+ });
327
+ traverseWithVariables(ast, function(node, type, allVars) {
328
+ if (type === 'name') {
329
+ var ident = node[1];
330
+ if (ident in values && allVars.indexOf(ident) < 0) {
331
+ return copy(values[ident]);
332
+ }
333
+ }
334
+ });
335
+ }
336
+
337
+ // Closure compiler, when inlining, will insert assignments to
338
+ // undefined for the shared variables. However, in compiled code
339
+ // - and in library/shell code too! - we should never rely on
340
+ // undefined being assigned. So we can simply remove those assignments.
341
+ //
342
+ // Note: An inlined function that kept a large value referenced, may
343
+ // keep that references when inlined, if we remove the setting to
344
+ // undefined. This is not dangerous in compiled code, but might be
345
+ // in supporting code (for example, holding on to the HEAP when copying).
346
+ //
347
+ // This pass assumes that unGlobalize has been run, so undefined
348
+ // is now explicit.
349
+ function removeAssignsToUndefined(ast) {
350
+ traverse(ast, function(node, type) {
351
+ if (type === 'assign' && jsonCompare(node[3], ['unary-prefix', 'void', ['num', 0]])) {
352
+ return emptyNode();
353
+ } else if (type === 'var') {
354
+ node[1] = node[1].map(function(varItem, j) {
355
+ var ident = varItem[0];
356
+ var value = varItem[1];
357
+ if (jsonCompare(value, UNDEFINED_NODE)) return [ident];
358
+ return [ident, value];
359
+ });
360
+ }
361
+ });
362
+ // cleanup (|x = y = void 0| leaves |x = ;| right now)
363
+ var modified = true;
364
+ while (modified) {
365
+ modified = false;
366
+ traverse(ast, function(node, type) {
367
+ if (type === 'assign' && jsonCompare(node[3], emptyNode())) {
368
+ modified = true;
369
+ return emptyNode();
370
+ } else if (type === 'var') {
371
+ node[1] = node[1].map(function(varItem, j) {
372
+ var ident = varItem[0];
373
+ var value = varItem[1];
374
+ if (value && jsonCompare(value, emptyNode())) return [ident];
375
+ return [ident, value];
376
+ });
377
+ }
378
+ });
379
+ }
380
+ }
381
+
382
+ // XXX This is an invalid optimization
383
+ // We sometimes leave some settings to label that are not needed, if later in
384
+ // the relooper we realize that we have a single entry, so no checks on label
385
+ // are actually necessary. It's easy to clean those up now.
386
+ function removeUnneededLabelSettings(ast) {
387
+ traverse(ast, function(node, type) {
388
+ if (type === 'defun') { // all of our compiled code is in defun nodes
389
+ // Find all checks
390
+ var checked = {};
391
+ traverse(node, function(node, type) {
392
+ if (type === 'binary' && node[1] === '==' && node[2][0] === 'name' && node[2][1] === 'label') {
393
+ assert(node[3][0] === 'num');
394
+ checked[node[3][1]] = 1;
395
+ }
396
+ });
397
+ // Remove unneeded sets
398
+ traverse(node, function(node, type) {
399
+ if (type === 'assign' && node[2][0] === 'name' && node[2][1] === 'label') {
400
+ assert(node[3][0] === 'num');
401
+ if (!(node[3][1] in checked)) return emptyNode();
402
+ }
403
+ });
404
+ }
405
+ });
406
+ }
407
+
408
+ // Various expression simplifications. Pre run before closure (where we still have metadata), Post run after.
409
+
410
+ var USEFUL_BINARY_OPS = set('<<', '>>', '|', '&', '^');
411
+ var COMPARE_OPS = set('<', '<=', '>', '>=', '==', '===', '!=', '!==');
412
+
413
+ function simplifyExpressionsPre(ast) {
414
+ // Simplify common expressions used to perform integer conversion operations
415
+ // in cases where no conversion is needed.
416
+ function simplifyIntegerConversions(ast) {
417
+ traverse(ast, function(node, type) {
418
+ if (type === 'binary' && node[1] === '>>' && node[3][0] === 'num' &&
419
+ node[2][0] === 'binary' && node[2][1] === '<<' && node[2][3][0] === 'num' && node[3][1] === node[2][3][1]) {
420
+ // Transform (x&A)<<B>>B to X&A.
421
+ var innerNode = node[2][2];
422
+ var shifts = node[3][1];
423
+ if (innerNode[0] === 'binary' && innerNode[1] === '&' && innerNode[3][0] === 'num') {
424
+ var mask = innerNode[3][1];
425
+ if (mask << shifts >> shifts === mask) {
426
+ return innerNode;
427
+ }
428
+ }
429
+ } else if (type === 'binary' && node[1] === '&' && node[3][0] === 'num') {
430
+ // Rewrite (X < Y) & 1 to (X < Y)|0. (Subsequent passes will eliminate
431
+ // the |0 if possible.)
432
+ var input = node[2];
433
+ var amount = node[3][1];
434
+ if (input[0] === 'binary' && (input[1] in COMPARE_OPS) && amount == 1) {
435
+ node[1] = '|';
436
+ node[3][1] = 0;
437
+ }
438
+ }
439
+ });
440
+ }
441
+
442
+ // When there is a bunch of math like (((8+5)|0)+12)|0, only the external |0 is needed, one correction is enough.
443
+ // At each node, ((X|0)+Y)|0 can be transformed into (X+Y): The inner corrections are not needed
444
+ // TODO: Is the same is true for 0xff, 0xffff?
445
+ // Likewise, if we have |0 inside a block that will be >>'d, then the |0 is unnecessary because some
446
+ // 'useful' mathops already |0 anyhow.
447
+
448
+ function simplifyBitops(ast) {
449
+ var SAFE_BINARY_OPS;
450
+ if (asm) {
451
+ SAFE_BINARY_OPS = set('+', '-'); // division is unsafe as it creates non-ints in JS; mod is unsafe as signs matter so we can't remove |0's; mul does not nest with +,- in asm
452
+ } else {
453
+ SAFE_BINARY_OPS = set('+', '-', '*');
454
+ }
455
+ var COERCION_REQUIRING_OPS = set('sub', 'unary-prefix'); // ops that in asm must be coerced right away
456
+ var COERCION_REQUIRING_BINARIES = set('*', '/', '%'); // binary ops that in asm must be coerced
457
+ var ZERO = ['num', 0];
458
+
459
+ function removeMultipleOrZero() {
460
+ var rerun = true;
461
+ while (rerun) {
462
+ rerun = false;
463
+ traverse(ast, function process(node, type, stack) {
464
+ if (type === 'binary' && node[1] === '|') {
465
+ if (node[2][0] === 'num' && node[3][0] === 'num') {
466
+ node[2][1] |= node[3][1];
467
+ return node[2];
468
+ }
469
+ var go = false;
470
+ if (jsonCompare(node[2], ZERO)) {
471
+ // canonicalize order
472
+ var temp = node[3];
473
+ node[3] = node[2];
474
+ node[2] = temp;
475
+ go = true;
476
+ } else if (jsonCompare(node[3], ZERO)) {
477
+ go = true;
478
+ }
479
+ if (!go) {
480
+ stack.push(1);
481
+ return;
482
+ }
483
+ // We might be able to remove this correction
484
+ for (var i = stack.length-1; i >= 0; i--) {
485
+ if (stack[i] >= 1) {
486
+ if (asm) {
487
+ if (stack[stack.length-1] < 2 && node[2][0] === 'call') break; // we can only remove multiple |0s on these
488
+ if (stack[stack.length-1] < 1 && (node[2][0] in COERCION_REQUIRING_OPS ||
489
+ (node[2][0] === 'binary' && node[2][1] in COERCION_REQUIRING_BINARIES))) break; // we can remove |0 or >>2
490
+ }
491
+ // we will replace ourselves with the non-zero side. Recursively process that node.
492
+ var result = jsonCompare(node[2], ZERO) ? node[3] : node[2], other;
493
+ // replace node in-place
494
+ node.length = result.length;
495
+ for (var j = 0; j < result.length; j++) {
496
+ node[j] = result[j];
497
+ }
498
+ rerun = true;
499
+ return process(result, result[0], stack);
500
+ } else if (stack[i] === -1) {
501
+ break; // Too bad, we can't
502
+ }
503
+ }
504
+ stack.push(2); // From here on up, no need for this kind of correction, it's done at the top
505
+ // (Add this at the end, so it is only added if we did not remove it)
506
+ } else if (type === 'binary' && node[1] in USEFUL_BINARY_OPS) {
507
+ stack.push(1);
508
+ } else if ((type === 'binary' && node[1] in SAFE_BINARY_OPS) || type === 'num' || type === 'name') {
509
+ stack.push(0); // This node is safe in that it does not interfere with this optimization
510
+ } else if (type === 'unary-prefix' && node[1] === '~') {
511
+ stack.push(1);
512
+ } else {
513
+ stack.push(-1); // This node is dangerous! Give up if you see this before you see '1'
514
+ }
515
+ }, null, []);
516
+ }
517
+ }
518
+
519
+ removeMultipleOrZero();
520
+
521
+ // & and heap-related optimizations
522
+
523
+ var heapBits, heapUnsigned;
524
+ function parseHeap(name) {
525
+ if (name.substr(0, 4) != 'HEAP') return false;
526
+ heapUnsigned = name[4] === 'U';
527
+ heapBits = parseInt(name.substr(heapUnsigned ? 5 : 4));
528
+ return true;
529
+ }
530
+
531
+ var hasTempDoublePtr = false, rerunOrZeroPass = false;
532
+
533
+ traverse(ast, function(node, type) {
534
+ if (type === 'name') {
535
+ if (node[1] === 'tempDoublePtr') hasTempDoublePtr = true;
536
+ } else if (type === 'binary' && node[1] === '&' && node[3][0] === 'num') {
537
+ if (node[2][0] === 'num') return ['num', node[2][1] & node[3][1]];
538
+ var input = node[2];
539
+ var amount = node[3][1];
540
+ if (input[0] === 'binary' && input[1] === '&' && input[3][0] === 'num') {
541
+ // Collapse X & 255 & 1
542
+ node[3][1] = amount & input[3][1];
543
+ node[2] = input[2];
544
+ } else if (input[0] === 'sub' && input[1][0] === 'name') {
545
+ // HEAP8[..] & 255 => HEAPU8[..]
546
+ var name = input[1][1];
547
+ if (parseHeap(name)) {
548
+ if (amount === Math.pow(2, heapBits)-1) {
549
+ if (!heapUnsigned) {
550
+ input[1][1] = 'HEAPU' + heapBits; // make unsigned
551
+ }
552
+ if (asm) {
553
+ // we cannot return HEAPU8 without a coercion, but at least we do HEAP8 & 255 => HEAPU8 | 0
554
+ node[1] = '|';
555
+ node[3][1] = 0;
556
+ return node;
557
+ }
558
+ return input;
559
+ }
560
+ }
561
+ }
562
+ } else if (type === 'binary' && node[1] === '^') {
563
+ // LLVM represents bitwise not as xor with -1. Translate it back to an actual bitwise not.
564
+ if (node[3][0] === 'unary-prefix' && node[3][1] === '-' && node[3][2][0] === 'num' &&
565
+ node[3][2][1] === 1 &&
566
+ !(node[2][0] == 'unary-prefix' && node[2][1] == '~')) { // avoid creating ~~~ which is confusing for asm given the role of ~~
567
+ return ['unary-prefix', '~', node[2]];
568
+ }
569
+ } else if (type === 'binary' && node[1] === '>>' && node[3][0] === 'num' &&
570
+ node[2][0] === 'binary' && node[2][1] === '<<' && node[2][3][0] === 'num' &&
571
+ node[2][2][0] === 'sub' && node[2][2][1][0] === 'name') {
572
+ // collapse HEAPU?8[..] << 24 >> 24 etc. into HEAP8[..] | 0
573
+ var amount = node[3][1];
574
+ var name = node[2][2][1][1];
575
+ if (amount === node[2][3][1] && parseHeap(name)) {
576
+ if (heapBits === 32 - amount) {
577
+ node[2][2][1][1] = 'HEAP' + heapBits;
578
+ node[1] = '|';
579
+ node[2] = node[2][2];
580
+ node[3][1] = 0;
581
+ rerunOrZeroPass = true;
582
+ return node;
583
+ }
584
+ }
585
+ } else if (type === 'assign') {
586
+ // optimizations for assigning into HEAP32 specifically
587
+ if (node[1] === true && node[2][0] === 'sub' && node[2][1][0] === 'name' && node[2][1][1] === 'HEAP32') {
588
+ // HEAP32[..] = x | 0 does not need the | 0 (unless it is a mandatory |0 of a call)
589
+ if (node[3][0] === 'binary' && node[3][1] === '|') {
590
+ if (node[3][2][0] === 'num' && node[3][2][1] === 0 && node[3][3][0] != 'call') {
591
+ node[3] = node[3][3];
592
+ } else if (node[3][3][0] === 'num' && node[3][3][1] === 0 && node[3][2][0] != 'call') {
593
+ node[3] = node[3][2];
594
+ }
595
+ }
596
+ }
597
+ var value = node[3];
598
+ if (value[0] === 'binary' && value[1] === '|') {
599
+ // canonicalize order of |0 to end
600
+ if (value[2][0] === 'num' && value[2][1] === 0) {
601
+ var temp = value[2];
602
+ value[2] = value[3];
603
+ value[3] = temp;
604
+ }
605
+ // if a seq ends in an |0, remove an external |0
606
+ // note that it is only safe to do this in assigns, like we are doing here (return (x, y|0); is not valid)
607
+ if (value[2][0] === 'seq' && value[2][2][0] === 'binary' && value[2][2][1] in USEFUL_BINARY_OPS) {
608
+ node[3] = value[2];
609
+ }
610
+ }
611
+ } else if (type == 'sub' && node[1][0] == 'name' && /^FUNCTION_TABLE.*/.exec(node[1][1])) {
612
+ return null; // do not traverse subchildren here, we should not collapse 55 & 126. TODO: optimize this into a nonvirtual call (also because we lose some other opts here)!
613
+ }
614
+ });
615
+
616
+ if (rerunOrZeroPass) removeMultipleOrZero();
617
+
618
+ if (asm) {
619
+ if (hasTempDoublePtr) {
620
+ traverse(ast, function(node, type) {
621
+ if (type === 'assign') {
622
+ if (node[1] === true && node[2][0] === 'sub' && node[2][1][0] === 'name' && node[2][1][1] === 'HEAP32') {
623
+ // remove bitcasts that are now obviously pointless, e.g.
624
+ // HEAP32[$45 >> 2] = HEAPF32[tempDoublePtr >> 2] = ($14 < $28 ? $14 : $28) - $42, HEAP32[tempDoublePtr >> 2] | 0;
625
+ var value = node[3];
626
+ if (value[0] === 'seq' && value[1][0] === 'assign' && value[1][2][0] === 'sub' && value[1][2][1][0] === 'name' && value[1][2][1][1] === 'HEAPF32' &&
627
+ value[1][2][2][0] === 'binary' && value[1][2][2][2][0] === 'name' && value[1][2][2][2][1] === 'tempDoublePtr') {
628
+ // transform to HEAPF32[$45 >> 2] = ($14 < $28 ? $14 : $28) - $42;
629
+ node[2][1][1] = 'HEAPF32';
630
+ node[3] = value[1][3];
631
+ }
632
+ }
633
+ } else if (type === 'seq') {
634
+ // (HEAP32[tempDoublePtr >> 2] = HEAP32[$37 >> 2], +HEAPF32[tempDoublePtr >> 2])
635
+ // ==>
636
+ // +HEAPF32[$37 >> 2]
637
+ if (node[0] === 'seq' && node[1][0] === 'assign' && node[1][2][0] === 'sub' && node[1][2][1][0] === 'name' &&
638
+ (node[1][2][1][1] === 'HEAP32' || node[1][2][1][1] === 'HEAPF32') &&
639
+ node[1][2][2][0] === 'binary' && node[1][2][2][2][0] === 'name' && node[1][2][2][2][1] === 'tempDoublePtr' &&
640
+ node[1][3][0] === 'sub' && node[1][3][1][0] === 'name' && (node[1][3][1][1] === 'HEAP32' || node[1][3][1][1] === 'HEAPF32') &&
641
+ node[2][0] !== 'seq') { // avoid (x, y, z) which can be used for tempDoublePtr on doubles for alignment fixes
642
+ if (node[1][2][1][1] === 'HEAP32') {
643
+ node[1][3][1][1] = 'HEAPF32';
644
+ return ['unary-prefix', '+', node[1][3]];
645
+ } else {
646
+ node[1][3][1][1] = 'HEAP32';
647
+ return ['binary', '|', node[1][3], ['num', 0]];
648
+ }
649
+ }
650
+ }
651
+ });
652
+
653
+ // finally, wipe out remaining ones by finding cases where all assignments to X are bitcasts, and all uses are writes to
654
+ // the other heap type, then eliminate the bitcast
655
+ var bitcastVars = {};
656
+ traverse(ast, function(node, type) {
657
+ if (type === 'assign' && node[1] === true && node[2][0] === 'name') {
658
+ var value = node[3];
659
+ if (value[0] === 'seq' && value[1][0] === 'assign' && value[1][2][0] === 'sub' && value[1][2][1][0] === 'name' &&
660
+ (value[1][2][1][1] === 'HEAP32' || value[1][2][1][1] === 'HEAPF32') &&
661
+ value[1][2][2][0] === 'binary' && value[1][2][2][2][0] === 'name' && value[1][2][2][2][1] === 'tempDoublePtr') {
662
+ var name = node[2][1];
663
+ if (!bitcastVars[name]) bitcastVars[name] = {
664
+ define_HEAP32: 0, define_HEAPF32: 0, use_HEAP32: 0, use_HEAPF32: 0, bad: false, namings: 0, defines: [], uses: []
665
+ };
666
+ bitcastVars[name]['define_' + value[1][2][1][1]]++;
667
+ bitcastVars[name].defines.push(node);
668
+ }
669
+ }
670
+ });
671
+ traverse(ast, function(node, type) {
672
+ if (type === 'name' && bitcastVars[node[1]]) {
673
+ bitcastVars[node[1]].namings++;
674
+ } else if (type === 'assign' && node[1] === true) {
675
+ var value = node[3];
676
+ if (value[0] === 'name') {
677
+ var name = value[1];
678
+ if (bitcastVars[name]) {
679
+ var target = node[2];
680
+ if (target[0] === 'sub' && target[1][0] === 'name' && (target[1][1] === 'HEAP32' || target[1][1] === 'HEAPF32')) {
681
+ bitcastVars[name]['use_' + target[1][1]]++;
682
+ bitcastVars[name].uses.push(node);
683
+ }
684
+ }
685
+ }
686
+ }
687
+ });
688
+ var asmData = normalizeAsm(ast);
689
+ for (var v in bitcastVars) {
690
+ var info = bitcastVars[v];
691
+ // good variables define only one type, use only one type, have definitions and uses, and define as a different type than they use
692
+ if (info.define_HEAP32*info.define_HEAPF32 === 0 && info.use_HEAP32*info.use_HEAPF32 === 0 &&
693
+ info.define_HEAP32+info.define_HEAPF32 > 0 && info.use_HEAP32+info.use_HEAPF32 > 0 &&
694
+ info.define_HEAP32*info.use_HEAP32 === 0 && info.define_HEAPF32*info.use_HEAPF32 === 0 &&
695
+ v in asmData.vars && info.namings === info.define_HEAP32+info.define_HEAPF32+info.use_HEAP32+info.use_HEAPF32) {
696
+ var correct = info.use_HEAP32 ? 'HEAPF32' : 'HEAP32';
697
+ info.defines.forEach(function(define) {
698
+ define[3] = define[3][1][3];
699
+ if (correct === 'HEAP32') {
700
+ define[3] = ['binary', '|', define[3], ['num', 0]];
701
+ } else {
702
+ define[3] = ['unary-prefix', '+', define[3]];
703
+ }
704
+ // do we want a simplifybitops on the new values here?
705
+ });
706
+ info.uses.forEach(function(use) {
707
+ use[2][1][1] = correct;
708
+ });
709
+ asmData.vars[v] = 1 - asmData.vars[v];
710
+ }
711
+ }
712
+ denormalizeAsm(ast, asmData);
713
+ }
714
+
715
+ // optimize num >> num, in asm we need this here since we do not run optimizeShifts
716
+ traverse(ast, function(node, type) {
717
+ if (type === 'binary' && node[1] === '>>' && node[2][0] === 'num' && node[3][0] === 'num') {
718
+ node[0] = 'num';
719
+ node[1] = node[2][1] >> node[3][1];
720
+ node.length = 2;
721
+ }
722
+ });
723
+ }
724
+ }
725
+
726
+ // The most common mathop is addition, e.g. in getelementptr done repeatedly. We can join all of those,
727
+ // by doing (num+num) ==> newnum, and (name+num)+num = name+newnum
728
+ function joinAdditions(ast) {
729
+ var rerun = true;
730
+ while (rerun) {
731
+ rerun = false;
732
+ traverse(ast, function(node, type) {
733
+ if (type === 'binary' && node[1] === '+') {
734
+ if (node[2][0] === 'num' && node[3][0] === 'num') {
735
+ rerun = true;
736
+ node[2][1] += node[3][1];
737
+ return node[2];
738
+ }
739
+ for (var i = 2; i <= 3; i++) {
740
+ var ii = 5-i;
741
+ for (var j = 2; j <= 3; j++) {
742
+ if (node[i][0] === 'num' && node[ii][0] === 'binary' && node[ii][1] === '+' && node[ii][j][0] === 'num') {
743
+ rerun = true;
744
+ node[ii][j][1] += node[i][1];
745
+ return node[ii];
746
+ }
747
+ }
748
+ }
749
+ }
750
+ });
751
+ }
752
+ }
753
+
754
+ // if (x === 0) can be if (!x), etc.
755
+ function simplifyZeroComp(ast) {
756
+ traverse(ast, function(node, type) {
757
+ var binary;
758
+ if (type === 'if' && (binary = node[1])[0] === 'binary') {
759
+ if ((binary[1] === '!=' || binary[1] === '!==') && binary[3][0] === 'num' && binary[3][1] === 0) {
760
+ node[1] = binary[2];
761
+ return node;
762
+ } else if ((binary[1] === '==' || binary[1] === '===') && binary[3][0] === 'num' && binary[3][1] === 0) {
763
+ node[1] = ['unary-prefix', '!', binary[2]];
764
+ return node;
765
+ }
766
+ }
767
+ });
768
+ }
769
+
770
+ function asmOpts(fun) {
771
+ // Add final returns when necessary
772
+ var returnType = null;
773
+ traverse(fun, function(node, type) {
774
+ if (type === 'return' && node[1]) {
775
+ returnType = detectAsmCoercion(node[1]);
776
+ }
777
+ });
778
+ // Add a final return if one is missing.
779
+ if (returnType !== null) {
780
+ var stats = getStatements(fun);
781
+ var last = stats[stats.length-1];
782
+ if (last[0] != 'return') {
783
+ var returnValue = ['num', 0];
784
+ if (returnType === ASM_DOUBLE) returnValue = ['unary-prefix', '+', returnValue];
785
+ stats.push(['return', returnValue]);
786
+ }
787
+ }
788
+ }
789
+
790
+ traverseGeneratedFunctions(ast, function(func) {
791
+ simplifyIntegerConversions(func);
792
+ simplifyBitops(func);
793
+ joinAdditions(func);
794
+ // simplifyZeroComp(func); TODO: investigate performance
795
+ if (asm) asmOpts(func);
796
+ });
797
+ }
798
+
799
+ // In typed arrays mode 2, we can have
800
+ // HEAP[x >> 2]
801
+ // very often. We can in some cases do the shift on the variable itself when it is set,
802
+ // to greatly reduce the number of shift operations.
803
+ // TODO: when shifting a variable, if there are other uses, keep an unshifted version too, to prevent slowdowns?
804
+ function optimizeShiftsInternal(ast, conservative) {
805
+ var MAX_SHIFTS = 3;
806
+ traverseGeneratedFunctions(ast, function(fun) {
807
+ var funMore = true;
808
+ var funFinished = {};
809
+ while (funMore) {
810
+ funMore = false;
811
+ // Recognize variables and parameters
812
+ var vars = {};
813
+ function newVar(name, param, addUse) {
814
+ if (!vars[name]) {
815
+ vars[name] = {
816
+ param: param,
817
+ defs: addUse ? 1 : 0,
818
+ uses: 0,
819
+ timesShifted: [0, 0, 0, 0], // zero shifts of size 0, 1, 2, 3
820
+ benefit: 0,
821
+ primaryShift: -1
822
+ };
823
+ }
824
+ }
825
+ // params
826
+ if (fun[2]) {
827
+ fun[2].forEach(function(arg) {
828
+ newVar(arg, true, true);
829
+ });
830
+ }
831
+ // vars
832
+ // XXX if var has >>=, ignore it here? That means a previous pass already optimized it
833
+ var hasSwitch = traverse(fun, function(node, type) {
834
+ if (type === 'var') {
835
+ node[1].forEach(function(arg) {
836
+ newVar(arg[0], false, arg[1]);
837
+ });
838
+ } else if (type === 'switch') {
839
+ // The relooper can't always optimize functions, and we currently don't work with
840
+ // switch statements when optimizing shifts. Bail.
841
+ return true;
842
+ }
843
+ });
844
+ if (hasSwitch) {
845
+ break;
846
+ }
847
+ // uses and defs TODO: weight uses by being inside a loop (powers). without that, we
848
+ // optimize for code size, not speed.
849
+ traverse(fun, function(node, type, stack) {
850
+ stack.push(node);
851
+ if (type === 'name' && vars[node[1]] && stack[stack.length-2][0] != 'assign') {
852
+ vars[node[1]].uses++;
853
+ } else if (type === 'assign' && node[2][0] === 'name' && vars[node[2][1]]) {
854
+ vars[node[2][1]].defs++;
855
+ }
856
+ }, null, []);
857
+ // First, break up elements inside a shift. This lets us see clearly what to do next.
858
+ traverse(fun, function(node, type) {
859
+ if (type === 'binary' && node[1] === '>>' && node[3][0] === 'num') {
860
+ var shifts = node[3][1];
861
+ if (shifts <= MAX_SHIFTS) {
862
+ // Push the >> inside the value elements
863
+ function addShift(subNode) {
864
+ if (subNode[0] === 'binary' && subNode[1] === '+') {
865
+ subNode[2] = addShift(subNode[2]);
866
+ subNode[3] = addShift(subNode[3]);
867
+ return subNode;
868
+ }
869
+ if (subNode[0] === 'name' && !subNode[2]) { // names are returned with a shift, but we also note their being shifted
870
+ var name = subNode[1];
871
+ if (vars[name]) {
872
+ vars[name].timesShifted[shifts]++;
873
+ subNode[2] = true;
874
+ }
875
+ }
876
+ return ['binary', '>>', subNode, ['num', shifts]];
877
+ }
878
+ return addShift(node[2]);
879
+ }
880
+ }
881
+ });
882
+ traverse(fun, function(node, type) {
883
+ if (node[0] === 'name' && node[2]) {
884
+ return node.slice(0, 2); // clean up our notes
885
+ }
886
+ });
887
+ // At this point, shifted expressions are split up, and we know who the vars are and their info, so we can decide
888
+ // TODO: vars that depend on other vars
889
+ for (var name in vars) {
890
+ var data = vars[name];
891
+ var totalTimesShifted = sum(data.timesShifted);
892
+ if (totalTimesShifted === 0) {
893
+ continue;
894
+ }
895
+ if (totalTimesShifted != Math.max.apply(null, data.timesShifted)) {
896
+ // TODO: Handle multiple different shifts
897
+ continue;
898
+ }
899
+ if (funFinished[name]) continue;
900
+ // We have one shift size (and possible unshifted uses). Consider replacing this variable with a shifted clone. If
901
+ // the estimated benefit is >0, we will do it
902
+ if (data.defs === 1) {
903
+ data.benefit = totalTimesShifted - 2*(data.defs + (data.param ? 1 : 0));
904
+ }
905
+ if (conservative) data.benefit = 0;
906
+ if (data.benefit > 0) {
907
+ funMore = true; // We will reprocess this function
908
+ for (var i = 0; i < 4; i++) {
909
+ if (data.timesShifted[i]) {
910
+ data.primaryShift = i;
911
+ }
912
+ }
913
+ }
914
+ }
915
+ //printErr(JSON.stringify(vars));
916
+ function cleanNotes() { // We need to mark 'name' nodes as 'processed' in some passes here; this cleans the notes up
917
+ traverse(fun, function(node, type) {
918
+ if (node[0] === 'name' && node[2]) {
919
+ return node.slice(0, 2);
920
+ }
921
+ });
922
+ }
923
+ cleanNotes();
924
+ // Apply changes
925
+ function needsShift(name) {
926
+ return vars[name] && vars[name].primaryShift >= 0;
927
+ }
928
+ for (var name in vars) { // add shifts for params and var's for all new variables
929
+ var data = vars[name];
930
+ if (needsShift(name)) {
931
+ if (data.param) {
932
+ fun[3].unshift(['var', [[name + '$s' + data.primaryShift, ['binary', '>>', ['name', name], ['num', data.primaryShift]]]]]);
933
+ } else {
934
+ fun[3].unshift(['var', [[name + '$s' + data.primaryShift]]]);
935
+ }
936
+ }
937
+ }
938
+ traverse(fun, function(node, type, stack) { // add shift to assignments
939
+ stack.push(node);
940
+ if (node[0] === 'assign' && node[1] === true && node[2][0] === 'name' && needsShift(node[2][1]) && !node[2][2]) {
941
+ var name = node[2][1];
942
+ var data = vars[name];
943
+ var parent = stack[stack.length-3];
944
+ var statements = getStatements(parent);
945
+ assert(statements, 'Invalid parent for assign-shift: ' + dump(parent));
946
+ var i = statements.indexOf(stack[stack.length-2]);
947
+ statements.splice(i+1, 0, ['stat', ['assign', true, ['name', name + '$s' + data.primaryShift], ['binary', '>>', ['name', name, true], ['num', data.primaryShift]]]]);
948
+ } else if (node[0] === 'var') {
949
+ var args = node[1];
950
+ for (var i = 0; i < args.length; i++) {
951
+ var arg = args[i];
952
+ var name = arg[0];
953
+ var data = vars[name];
954
+ if (arg[1] && needsShift(name)) {
955
+ args.splice(i+1, 0, [name + '$s' + data.primaryShift, ['binary', '>>', ['name', name, true], ['num', data.primaryShift]]]);
956
+ }
957
+ }
958
+ return node;
959
+ }
960
+ }, null, []);
961
+ cleanNotes();
962
+ traverse(fun, function(node, type, stack) { // replace shifted name with new variable
963
+ stack.push(node);
964
+ if (node[0] === 'binary' && node[1] === '>>' && node[2][0] === 'name' && needsShift(node[2][1]) && node[3][0] === 'num') {
965
+ var name = node[2][1];
966
+ var data = vars[name];
967
+ var parent = stack[stack.length-2];
968
+ // Don't modify in |x$sN = x >> 2|, in normal assigns and in var assigns
969
+ if (parent[0] === 'assign' && parent[2][0] === 'name' && parent[2][1] === name + '$s' + data.primaryShift) return;
970
+ if (parent[0] === name + '$s' + data.primaryShift) return;
971
+ if (node[3][1] === data.primaryShift) {
972
+ return ['name', name + '$s' + data.primaryShift];
973
+ }
974
+ }
975
+ }, null, []);
976
+ cleanNotes();
977
+ var SIMPLE_SHIFTS = set('<<', '>>');
978
+ var more = true;
979
+ while (more) { // combine shifts in the same direction as an optimization
980
+ more = false;
981
+ traverse(fun, function(node, type) {
982
+ if (node[0] === 'binary' && node[1] in SIMPLE_SHIFTS && node[2][0] === 'binary' && node[2][1] === node[1] &&
983
+ node[3][0] === 'num' && node[2][3][0] === 'num') { // do not turn a << b << c into a << b + c; while logically identical, it is slower
984
+ more = true;
985
+ return ['binary', node[1], node[2][2], ['num', node[3][1] + node[2][3][1]]];
986
+ }
987
+ });
988
+ }
989
+ // Before recombining, do some additional optimizations
990
+ traverse(fun, function(node, type) {
991
+ // Apply constant shifts onto constants
992
+ if (type === 'binary' && node[1] === '>>' && node[2][0] === 'num' && node[3][0] === 'num' && node[3][1] <= MAX_SHIFTS) {
993
+ var subNode = node[2];
994
+ var shifts = node[3][1];
995
+ var result = subNode[1] / Math.pow(2, shifts);
996
+ if (result % 1 === 0) {
997
+ subNode[1] = result;
998
+ return subNode;
999
+ }
1000
+ }
1001
+ // Optimize the case of ($a*80)>>2 into ($a*20)|0
1002
+ if (type === 'binary' && node[1] in SIMPLE_SHIFTS &&
1003
+ node[2][0] === 'binary' && node[2][1] === '*') {
1004
+ var mulNode = node[2];
1005
+ if (mulNode[2][0] === 'num') {
1006
+ var temp = mulNode[2];
1007
+ mulNode[2] = mulNode[3];
1008
+ mulNode[3] = temp;
1009
+ }
1010
+ if (mulNode[3][0] === 'num') {
1011
+ if (node[1] === '<<') {
1012
+ mulNode[3][1] *= Math.pow(2, node[3][1]);
1013
+ node[1] = '|';
1014
+ node[3][1] = 0;
1015
+ return node;
1016
+ } else {
1017
+ if (mulNode[3][1] % Math.pow(2, node[3][1]) === 0) {
1018
+ mulNode[3][1] /= Math.pow(2, node[3][1]);
1019
+ node[1] = '|';
1020
+ node[3][1] = 0;
1021
+ return node;
1022
+ }
1023
+ }
1024
+ }
1025
+ }
1026
+ /* XXX - theoretically useful optimization(s), but commented out as not helpful in practice
1027
+ // Transform (x << 2) >> 2 into x & mask or something even simpler
1028
+ if (type === 'binary' && node[1] === '>>' && node[3][0] === 'num' &&
1029
+ node[2][0] === 'binary' && node[2][1] === '<<' && node[2][3][0] === 'num' && node[3][1] === node[2][3][1]) {
1030
+ var subNode = node[2];
1031
+ var shifts = node[3][1];
1032
+ var mask = ((0xffffffff << shifts) >>> shifts) | 0;
1033
+ return ['binary', '&', subNode[2], ['num', mask]];
1034
+ //return ['binary', '|', subNode[2], ['num', 0]];
1035
+ //return subNode[2];
1036
+ }
1037
+ */
1038
+ });
1039
+ // Re-combine remaining shifts, to undo the breaking up we did before. may require reordering inside +'s
1040
+ traverse(fun, function(node, type, stack) {
1041
+ stack.push(node);
1042
+ if (type === 'binary' && node[1] === '+' && (stack[stack.length-2][0] != 'binary' || stack[stack.length-2][1] !== '+')) {
1043
+ // 'Flatten' added items
1044
+ var addedItems = [];
1045
+ function flatten(node) {
1046
+ if (node[0] === 'binary' && node[1] === '+') {
1047
+ flatten(node[2]);
1048
+ flatten(node[3]);
1049
+ } else {
1050
+ addedItems.push(node);
1051
+ }
1052
+ }
1053
+ flatten(node);
1054
+ var originalOrder = addedItems.slice();
1055
+ function key(node) { // a unique value for all relevant shifts for recombining, non-unique for stuff we don't need to bother with
1056
+ function originalOrderKey(item) {
1057
+ return -originalOrder.indexOf(item);
1058
+ }
1059
+ if (node[0] === 'binary' && node[1] in SIMPLE_SHIFTS) {
1060
+ if (node[3][0] === 'num' && node[3][1] <= MAX_SHIFTS) return 2*node[3][1] + (node[1] === '>>' ? 100 : 0); // 0-106
1061
+ return (node[1] === '>>' ? 20000 : 10000) + originalOrderKey(node);
1062
+ }
1063
+ if (node[0] === 'num') return -20000 + node[1];
1064
+ return -10000 + originalOrderKey(node); // Don't modify the original order if we don't modify anything
1065
+ }
1066
+ for (var i = 0; i < addedItems.length; i++) {
1067
+ if (addedItems[i][0] === 'string') return; // this node is not relevant for us
1068
+ }
1069
+ addedItems.sort(function(node1, node2) {
1070
+ return key(node1) - key(node2);
1071
+ });
1072
+ // Regenerate items, now sorted
1073
+ var i = 0;
1074
+ while (i < addedItems.length-1) { // re-combine inside addedItems
1075
+ var k = key(addedItems[i]), k1 = key(addedItems[i+1]);
1076
+ if (k === k1 && k >= 0 && k1 <= 106) {
1077
+ addedItems[i] = ['binary', addedItems[i][1], ['binary', '+', addedItems[i][2], addedItems[i+1][2]], addedItems[i][3]];
1078
+ addedItems.splice(i+1, 1);
1079
+ } else {
1080
+ i++;
1081
+ }
1082
+ }
1083
+ var num = 0;
1084
+ for (i = 0; i < addedItems.length; i++) { // combine all numbers into one
1085
+ if (addedItems[i][0] === 'num') {
1086
+ num += addedItems[i][1];
1087
+ addedItems.splice(i, 1);
1088
+ i--;
1089
+ }
1090
+ }
1091
+ if (num != 0) { // add the numbers into an existing shift, we
1092
+ // prefer (x+5)>>7 over (x>>7)+5 , since >>'s result is known to be 32-bit and is more easily optimized.
1093
+ // Also, in the former we can avoid the parentheses, which saves a little space (the number will be bigger,
1094
+ // so it might take more space, but normally at most one more digit).
1095
+ var added = false;
1096
+ for (i = 0; i < addedItems.length; i++) {
1097
+ if (addedItems[i][0] === 'binary' && addedItems[i][1] === '>>' && addedItems[i][3][0] === 'num' && addedItems[i][3][1] <= MAX_SHIFTS) {
1098
+ addedItems[i] = ['binary', '>>', ['binary', '+', addedItems[i][2], ['num', num << addedItems[i][3][1]]], addedItems[i][3]];
1099
+ added = true;
1100
+ }
1101
+ }
1102
+ if (!added) {
1103
+ addedItems.unshift(['num', num]);
1104
+ }
1105
+ }
1106
+ var ret = addedItems.pop();
1107
+ while (addedItems.length > 0) { // re-create AST from addedItems
1108
+ ret = ['binary', '+', ret, addedItems.pop()];
1109
+ }
1110
+ return ret;
1111
+ }
1112
+ }, null, []);
1113
+ // Note finished variables
1114
+ for (var name in vars) {
1115
+ funFinished[name] = true;
1116
+ }
1117
+ }
1118
+ });
1119
+ }
1120
+
1121
+ function optimizeShiftsConservative(ast) {
1122
+ optimizeShiftsInternal(ast, true);
1123
+ }
1124
+
1125
+ function optimizeShiftsAggressive(ast) {
1126
+ optimizeShiftsInternal(ast, false);
1127
+ }
1128
+
1129
+ // We often have branchings that are simplified so one end vanishes, and
1130
+ // we then get
1131
+ // if (!(x < 5))
1132
+ // or such. Simplifying these saves space and time.
1133
+ function simplifyNotCompsDirect(node) {
1134
+ if (node[0] === 'unary-prefix' && node[1] === '!') {
1135
+ if (node[2][0] === 'binary') {
1136
+ switch(node[2][1]) {
1137
+ case '<': return ['binary', '>=', node[2][2], node[2][3]];
1138
+ case '>': return ['binary', '<=', node[2][2], node[2][3]];
1139
+ case '<=': return ['binary', '>', node[2][2], node[2][3]];
1140
+ case '>=': return ['binary', '<', node[2][2], node[2][3]];
1141
+ case '==': return ['binary', '!=', node[2][2], node[2][3]];
1142
+ case '!=': return ['binary', '==', node[2][2], node[2][3]];
1143
+ case '===': return ['binary', '!==', node[2][2], node[2][3]];
1144
+ case '!==': return ['binary', '===', node[2][2], node[2][3]];
1145
+ }
1146
+ } else if (node[2][0] === 'unary-prefix' && node[2][1] === '!') {
1147
+ return node[2][2];
1148
+ }
1149
+ }
1150
+ if (!simplifyNotCompsPass) return node;
1151
+ }
1152
+
1153
+ var simplifyNotCompsPass = false;
1154
+
1155
+ function simplifyNotComps(ast) {
1156
+ simplifyNotCompsPass = true;
1157
+ traverse(ast, simplifyNotCompsDirect);
1158
+ simplifyNotCompsPass = false;
1159
+ }
1160
+
1161
+ function simplifyExpressionsPost(ast) {
1162
+ simplifyNotComps(ast);
1163
+ }
1164
+
1165
+ var NO_SIDE_EFFECTS = set('num', 'name');
1166
+
1167
+ function hasSideEffects(node) { // this is 99% incomplete!
1168
+ if (node[0] in NO_SIDE_EFFECTS) return false;
1169
+ if (node[0] === 'unary-prefix') return hasSideEffects(node[2]);
1170
+ if (node[0] === 'binary') return hasSideEffects(node[2]) || hasSideEffects(node[3]);
1171
+ return true;
1172
+ }
1173
+
1174
+ // Clear out empty ifs and blocks, and redundant blocks/stats and so forth
1175
+ // Operates on generated functions only
1176
+ function vacuum(ast) {
1177
+ function isEmpty(node) {
1178
+ if (!node) return true;
1179
+ if (node[0] === 'toplevel' && (!node[1] || node[1].length === 0)) return true;
1180
+ if (node[0] === 'block' && (!node[1] || (typeof node[1] != 'object') || node[1].length === 0 || (node[1].length === 1 && isEmpty(node[1])))) return true;
1181
+ return false;
1182
+ }
1183
+ function simplifyList(node, si) {
1184
+ var changed = false;
1185
+ // Merge block items into this list, thus removing unneeded |{ .. }|'s
1186
+ var statements = node[si];
1187
+ var i = 0;
1188
+ while (i < statements.length) {
1189
+ var subNode = statements[i];
1190
+ if (subNode[0] === 'block') {
1191
+ statements.splice.apply(statements, [i, 1].concat(subNode[1] || []));
1192
+ changed = true;
1193
+ } else {
1194
+ i++;
1195
+ }
1196
+ }
1197
+ // Remove empty items
1198
+ var pre = node[si].length;
1199
+ node[si] = node[si].filter(function(node) { return !isEmpty(node) });
1200
+ if (node[si].length < pre) changed = true;
1201
+ if (changed) {
1202
+ return node;
1203
+ }
1204
+ }
1205
+ function vacuumInternal(node) {
1206
+ traverseChildren(node, vacuumInternal);
1207
+ var ret;
1208
+ switch(node[0]) {
1209
+ case 'block': {
1210
+ if (node[1] && node[1].length === 1 && node[1][0][0] === 'block') {
1211
+ return node[1][0];
1212
+ } else if (typeof node[1] === 'object') {
1213
+ ret = simplifyList(node, 1);
1214
+ if (ret) return ret;
1215
+ }
1216
+ } break;
1217
+ case 'stat': {
1218
+ if (node[1][0] === 'block') {
1219
+ return node[1];
1220
+ }
1221
+ } break;
1222
+ case 'defun': {
1223
+ if (node[3].length === 1 && node[3][0][0] === 'block') {
1224
+ node[3] = node[3][0][1];
1225
+ return node;
1226
+ } else {
1227
+ ret = simplifyList(node, 3);
1228
+ if (ret) return ret;
1229
+ }
1230
+ } break;
1231
+ case 'do': {
1232
+ if (node[1][0] === 'num' && node[2][0] === 'toplevel' && (!node[2][1] || node[2][1].length === 0)) {
1233
+ return emptyNode();
1234
+ } else if (isEmpty(node[2]) && !hasSideEffects(node[1])) {
1235
+ return emptyNode();
1236
+ }
1237
+ } break;
1238
+ case 'label': {
1239
+ if (node[2][0] === 'toplevel' && (!node[2][1] || node[2][1].length === 0)) {
1240
+ return emptyNode();
1241
+ }
1242
+ } break;
1243
+ case 'if': {
1244
+ var empty2 = isEmpty(node[2]), empty3 = isEmpty(node[3]), has3 = node.length === 4;
1245
+ if (!empty2 && empty3 && has3) { // empty else clauses
1246
+ return node.slice(0, 3);
1247
+ } else if (empty2 && !empty3) { // empty if blocks
1248
+ return ['if', ['unary-prefix', '!', node[1]], node[3]];
1249
+ } else if (empty2 && empty3) {
1250
+ if (hasSideEffects(node[1])) {
1251
+ return ['stat', node[1]];
1252
+ } else {
1253
+ return emptyNode();
1254
+ }
1255
+ }
1256
+ } break;
1257
+ }
1258
+ }
1259
+ traverseGeneratedFunctions(ast, function(node) {
1260
+ vacuumInternal(node);
1261
+ simplifyNotComps(node);
1262
+ });
1263
+ }
1264
+
1265
+ function getStatements(node) {
1266
+ if (node[0] === 'defun') {
1267
+ return node[3];
1268
+ } else if (node[0] === 'block') {
1269
+ return node[1];
1270
+ } else {
1271
+ return null;
1272
+ }
1273
+ }
1274
+
1275
+ // Multiple blocks from the relooper are, in general, implemented by
1276
+ // if (label === x) { } else if ..
1277
+ // and branching into them by
1278
+ // if (condition) { label === x } else ..
1279
+ // We can hoist the multiple block into the condition, thus removing code and one 'if' check
1280
+ function hoistMultiples(ast) {
1281
+ traverseGeneratedFunctions(ast, function(node) {
1282
+ traverse(node, function(node, type) {
1283
+ var statements = getStatements(node);
1284
+ if (!statements) return;
1285
+ var modified = false;
1286
+ for (var i = 0; i < statements.length-1; i++) {
1287
+ var modifiedI = false;
1288
+ var pre = statements[i];
1289
+ if (pre[0] != 'if') continue;
1290
+ var post = statements[i+1];
1291
+ // Look into some block types. shell() will then recreate the shell that we looked into
1292
+ var postInner = post;
1293
+ var shellLabel = false, shellDo = false;
1294
+ while (true) {
1295
+ if (postInner[0] === 'label') {
1296
+ shellLabel = postInner[1];
1297
+ postInner = postInner[2];
1298
+ } else if (postInner[0] === 'do') {
1299
+ shellDo = postInner[1];
1300
+ postInner = postInner[2][1][0];
1301
+ } else {
1302
+ break; // give up
1303
+ }
1304
+ }
1305
+ if (postInner[0] != 'if') continue;
1306
+ // Look into this if, and its elseifs
1307
+ while (postInner && postInner[0] === 'if') {
1308
+ var cond = postInner[1];
1309
+ if (cond[0] === 'binary' && cond[1] === '==' && cond[2][0] === 'name' && cond[2][1] === 'label') {
1310
+ assert(cond[3][0] === 'num');
1311
+ // We have a valid Multiple check here. Try to hoist it, look for the source in |pre| and its else's
1312
+ var labelNum = cond[3][1];
1313
+ var labelBlock = postInner[2];
1314
+ assert(labelBlock[0] === 'block');
1315
+ var found = false;
1316
+ traverse(pre, function(preNode, preType) {
1317
+ if (!found && preType === 'assign' && preNode[2][0] === 'name' && preNode[2][1] === 'label') {
1318
+ assert(preNode[3][0] === 'num');
1319
+ if (preNode[3][1] === labelNum) {
1320
+ // That's it! Hoist away. We can also throw away the label setting as its goal has already been achieved
1321
+ found = true;
1322
+ modifiedI = true;
1323
+ postInner[2] = ['block', []];
1324
+ return labelBlock;
1325
+ }
1326
+ }
1327
+ });
1328
+ }
1329
+ postInner = postInner[3]; // Proceed to look in the else clause
1330
+ }
1331
+ if (modifiedI) {
1332
+ if (shellDo) {
1333
+ statements[i] = ['do', shellDo, ['block', [statements[i]]]];
1334
+ }
1335
+ if (shellLabel) {
1336
+ statements[i] = ['label', shellLabel, statements[i]];
1337
+ }
1338
+ }
1339
+ }
1340
+ if (modified) return node;
1341
+ });
1342
+
1343
+ // After hoisting in this function, it is safe to remove { label = x; } blocks, because
1344
+ // if they were leading to the next code right after them, they would be hoisted, and if they
1345
+ // are going to some other place entirely, they would break or continue. The only risky
1346
+ // situation is if the code after us is a multiple, in which case we might be checking for
1347
+ // this label inside it (or in a later multiple, even)
1348
+ function tryEliminate(node) {
1349
+ if (node[0] === 'if') {
1350
+ var replaced;
1351
+ if (replaced = tryEliminate(node[2])) node[2] = replaced;
1352
+ if (node[3] && (replaced = tryEliminate(node[3]))) node[3] = replaced;
1353
+ } else {
1354
+ if (node[0] === 'block' && node[1] && node[1].length > 0) {
1355
+ var subNode = node[1][node[1].length-1];
1356
+ if (subNode[0] === 'stat' && subNode[1][0] === 'assign' && subNode[1][2][0] === 'name' &&
1357
+ subNode[1][2][1] === 'label' && subNode[1][3][0] === 'num') {
1358
+ if (node[1].length === 1) {
1359
+ return emptyNode();
1360
+ } else {
1361
+ node[1].splice(node[1].length-1, 1);
1362
+ return node;
1363
+ }
1364
+ }
1365
+ }
1366
+ }
1367
+ return false;
1368
+ }
1369
+ function getActualStatement(node) { // find the actual active statement, ignoring a label and one-time do loop
1370
+ if (node[0] === 'label') node = node[2];
1371
+ if (node[0] === 'do') node = node[2];
1372
+ if (node[0] === 'block' && node[1].length === 1) node = node[1][0];
1373
+ return node;
1374
+ }
1375
+ vacuum(node);
1376
+ traverse(node, function(node, type) {
1377
+ var statements = getStatements(node);
1378
+ if (!statements) return;
1379
+ for (var i = 0; i < statements.length-1; i++) {
1380
+ var curr = getActualStatement(statements[i]);
1381
+ var next = statements[i+1];
1382
+ if (curr[0] === 'if' && next[0] != 'if' && next[0] != 'label' && next[0] != 'do' && next[0] != 'while') {
1383
+ tryEliminate(curr);
1384
+ }
1385
+ }
1386
+ });
1387
+ });
1388
+
1389
+ vacuum(ast);
1390
+
1391
+ // Afterpass: Reduce
1392
+ // if (..) { .. break|continue } else { .. }
1393
+ // to
1394
+ // if (..) { .. break|continue } ..
1395
+ traverseGenerated(ast, function(container, type) {
1396
+ var statements = getStatements(container);
1397
+ if (!statements) return;
1398
+ for (var i = 0; i < statements.length; i++) {
1399
+ var node = statements[i];
1400
+ if (node[0] === 'if' && node[2][0] === 'block' && node[3] && node[3][0] === 'block') {
1401
+ var stat1 = node[2][1], stat2 = node[3][1];
1402
+ // If break|continue in the latter and not the former, reverse them
1403
+ if (!(stat1[stat1.length-1][0] in LOOP_FLOW) && (stat2[stat2.length-1][0] in LOOP_FLOW)) {
1404
+ var temp = node[3];
1405
+ node[3] = node[2];
1406
+ node[2] = temp;
1407
+ node[1] = simplifyNotCompsDirect(['unary-prefix', '!', node[1]]);
1408
+ stat1 = node[2][1];
1409
+ stat2 = node[3][1];
1410
+ }
1411
+ if (stat1[stat1.length-1][0] in LOOP_FLOW) {
1412
+ statements.splice.apply(statements, [i+1, 0].concat(stat2));
1413
+ node[3] = null;
1414
+ }
1415
+ }
1416
+ }
1417
+ });
1418
+ }
1419
+
1420
+ // Simplifies loops
1421
+ // WARNING: This assumes all loops and breaks/continues are labelled
1422
+ function loopOptimizer(ast) {
1423
+ // Remove unneeded labels and one-time (do while(0)) loops. It is convenient to do these both at once.
1424
+ function passTwo(ast) {
1425
+ var neededDos = [];
1426
+ // Find unneeded labels
1427
+ traverseGenerated(ast, function(node, type, stack) {
1428
+ if (type === 'label' && node[2][0] in LOOP) {
1429
+ // this is a labelled loop. we don't know if it's needed yet. Mark its label for removal for now now.
1430
+ stack.push(node);
1431
+ node[1] = '+' + node[1];
1432
+ } else if (type in LOOP) {
1433
+ stack.push(node);
1434
+ } else if (type in LOOP_FLOW) {
1435
+ // Find topmost loop, and its label if there is one
1436
+ var lastLabel = null, lastLoop = null, i = stack.length-1;
1437
+ while (i >= 0 && !lastLoop) {
1438
+ if (stack[i][0] in LOOP) lastLoop = stack[i];
1439
+ i--;
1440
+ }
1441
+ assert(lastLoop, 'Cannot break/continue without a Label');
1442
+ while (i >= 0 && !lastLabel) {
1443
+ if (stack[i][0] in LOOP) break; // another loop in the middle - no label for lastLoop
1444
+ if (stack[i][0] === 'label') lastLabel = stack[i];
1445
+ i--;
1446
+ }
1447
+ var ident = node[1]; // there may not be a label ident if this is a simple break; or continue;
1448
+ var plus = '+' + ident;
1449
+ if (lastLabel && ident && (ident === lastLabel[1] || plus === lastLabel[1])) {
1450
+ // If this is a 'do' loop, this break means we actually need it.
1451
+ neededDos.push(lastLoop);
1452
+ // We don't need the control flow command to have a label - it's referring to the current loop
1453
+ return [node[0]];
1454
+ } else {
1455
+ if (!ident) {
1456
+ // No label on the break/continue, so keep the last loop alive (no need for its label though)
1457
+ neededDos.push(lastLoop);
1458
+ } else {
1459
+ // Find the label node that needs to stay alive
1460
+ stack.forEach(function(label) {
1461
+ if (!label) return;
1462
+ if (label[1] === plus) label[1] = label[1].substr(1); // Remove '+', marking it as needed
1463
+ });
1464
+ }
1465
+ }
1466
+ }
1467
+ }, null, []);
1468
+ // We return whether another pass is necessary
1469
+ var more = false;
1470
+ // Remove unneeded labels
1471
+ traverseGenerated(ast, function(node, type) {
1472
+ if (type === 'label' && node[1][0] === '+') {
1473
+ more = true;
1474
+ var ident = node[1].substr(1);
1475
+ // Remove label from loop flow commands
1476
+ traverse(node[2], function(node2, type) {
1477
+ if (type in LOOP_FLOW && node2[1] === ident) {
1478
+ return [node2[0]];
1479
+ }
1480
+ });
1481
+ return node[2]; // Remove the label itself on the loop
1482
+ }
1483
+ });
1484
+ // Remove unneeded one-time loops. We need such loops if (1) they have a label, or (2) they have a direct break so they are in neededDos.
1485
+ // First, add all labeled loops of this nature to neededDos
1486
+ traverseGenerated(ast, function(node, type) {
1487
+ if (type === 'label' && node[2][0] === 'do') {
1488
+ neededDos.push(node[2]);
1489
+ }
1490
+ });
1491
+ // Remove unneeded dos, we know who they are now
1492
+ traverseGenerated(ast, function(node, type) {
1493
+ if (type === 'do' && neededDos.indexOf(node) < 0) {
1494
+ assert(jsonCompare(node[1], ['num', 0]), 'Trying to remove a one-time do loop that is not one of our generated ones.;');
1495
+ more = true;
1496
+ return node[2];
1497
+ }
1498
+ });
1499
+ return more;
1500
+ }
1501
+
1502
+ // Go
1503
+
1504
+ // TODO: pass 1: Removal of unneeded continues, breaks if they get us to where we are already going. That will
1505
+ // help the next pass.
1506
+
1507
+ // Multiple pass two runs may be needed, as we remove one-time loops and so forth
1508
+ do {
1509
+ var more = passTwo(ast);
1510
+ vacuum(ast);
1511
+ } while (more);
1512
+
1513
+ vacuum(ast);
1514
+ }
1515
+
1516
+ function unVarify(vars, ret) { // transform var x=1, y=2 etc. into (x=1, y=2), i.e., the same assigns, but without a var definition
1517
+ ret = ret || [];
1518
+ ret[0] = 'stat';
1519
+ if (vars.length === 1) {
1520
+ ret[1] = ['assign', true, ['name', vars[0][0]], vars[0][1]];
1521
+ } else {
1522
+ ret[1] = [];
1523
+ var curr = ret[1];
1524
+ for (var i = 0; i < vars.length-1; i++) {
1525
+ curr[0] = 'seq';
1526
+ curr[1] = ['assign', true, ['name', vars[i][0]], vars[i][1]];
1527
+ if (i != vars.length-2) curr = curr[2] = [];
1528
+ }
1529
+ curr[2] = ['assign', true, ['name', vars[vars.length-1][0]], vars[vars.length-1][1]];
1530
+ }
1531
+ return ret;
1532
+ }
1533
+
1534
+ // asm.js support code - normalize (convert asm.js code to 'normal' JS, without
1535
+ // annotations, plus explicit metadata) and denormalize (vice versa)
1536
+ var ASM_INT = 0;
1537
+ var ASM_DOUBLE = 1;
1538
+
1539
+ function detectAsmCoercion(node, asmInfo) {
1540
+ // for params, +x vs x|0, for vars, 0.0 vs 0
1541
+ if (node[0] === 'num' && node[1].toString().indexOf('.') >= 0) return ASM_DOUBLE;
1542
+ if (node[0] === 'unary-prefix') return ASM_DOUBLE;
1543
+ if (asmInfo && node[0] == 'name') {
1544
+ if (node[1] in asmInfo.vars) return asmInfo.vars[node[1]];
1545
+ if (node[1] in asmInfo.params) return asmInfo.params[node[1]];
1546
+ }
1547
+ return ASM_INT;
1548
+ }
1549
+
1550
+ function makeAsmParamCoercion(param, type) {
1551
+ return type === ASM_INT ? ['binary', '|', ['name', param], ['num', 0]] : ['unary-prefix', '+', ['name', param]];
1552
+ }
1553
+
1554
+ function makeAsmVarDef(v, type) {
1555
+ return [v, type === ASM_INT ? ['num', 0] : ['unary-prefix', '+', ['num', 0]]];
1556
+ }
1557
+
1558
+ function getAsmType(asmInfo, name) {
1559
+ if (name in asmInfo.vars) return asmInfo.vars[name];
1560
+ return asmInfo.params[name];
1561
+ }
1562
+
1563
+ function normalizeAsm(func) {
1564
+ //printErr('pre-normalize \n\n' + astToSrc(func) + '\n\n');
1565
+ var data = {
1566
+ params: {}, // ident => ASM_* type
1567
+ vars: {}, // ident => ASM_* type
1568
+ };
1569
+ // process initial params
1570
+ var stats = func[3];
1571
+ var i = 0;
1572
+ while (i < stats.length) {
1573
+ var node = stats[i];
1574
+ if (node[0] != 'stat' || node[1][0] != 'assign' || node[1][2][0] != 'name') break;
1575
+ node = node[1];
1576
+ var name = node[2][1];
1577
+ if (func[2] && func[2].indexOf(name) < 0) break; // not an assign into a parameter, but a global
1578
+ data.params[name] = detectAsmCoercion(node[3]);
1579
+ stats[i] = emptyNode();
1580
+ i++;
1581
+ }
1582
+ // process initial variable definitions
1583
+ outer:
1584
+ while (i < stats.length) {
1585
+ var node = stats[i];
1586
+ if (node[0] != 'var') break;
1587
+ for (var j = 0; j < node[1].length; j++) {
1588
+ var v = node[1][j];
1589
+ var name = v[0];
1590
+ var value = v[1];
1591
+ if (!(name in data.vars)) {
1592
+ assert(value[0] === 'num' || (value[0] === 'unary-prefix' && value[2][0] === 'num')); // must be valid coercion no-op
1593
+ data.vars[name] = detectAsmCoercion(value);
1594
+ v.length = 1; // make an un-assigning var
1595
+ } else {
1596
+ break outer;
1597
+ }
1598
+ }
1599
+ i++;
1600
+ }
1601
+ // finally, look for other var definitions and collect them
1602
+ while (i < stats.length) {
1603
+ traverse(stats[i], function(node, type) {
1604
+ if (type === 'var') {
1605
+ for (var j = 0; j < node[1].length; j++) {
1606
+ var v = node[1][j];
1607
+ var name = v[0];
1608
+ var value = v[1];
1609
+ if (!(name in data.vars)) {
1610
+ if (value[0] != 'name') {
1611
+ data.vars[name] = detectAsmCoercion(value); // detect by coercion
1612
+ } else {
1613
+ var origin = value[1];
1614
+ data.vars[name] = data.vars[origin] || ASM_INT; // detect by origin variable, or assume int for non-locals
1615
+ }
1616
+ }
1617
+ }
1618
+ unVarify(node[1], node);
1619
+ } else if (type === 'dot') {
1620
+ if (node[1][0] === 'name' && node[1][1] === 'Math') {
1621
+ // transform Math.max to Math_max; we forward in the latter version
1622
+ node[0] = 'name';
1623
+ node[1] = 'Math_' + node[2];
1624
+ }
1625
+ }
1626
+ });
1627
+ i++;
1628
+ }
1629
+ //printErr('normalized \n\n' + astToSrc(func) + '\n\nwith: ' + JSON.stringify(data));
1630
+ return data;
1631
+ }
1632
+
1633
+ function denormalizeAsm(func, data) {
1634
+ //printErr('pre-denormalize \n\n' + astToSrc(func) + '\n\nwith: ' + JSON.stringify(data));
1635
+ var stats = func[3];
1636
+ // Remove var definitions, if any
1637
+ for (var i = 0; i < stats.length; i++) {
1638
+ if (stats[i][0] === 'var') {
1639
+ stats[i] = emptyNode();
1640
+ } else {
1641
+ if (!isEmptyNode(stats[i])) break;
1642
+ }
1643
+ }
1644
+ // each param needs a line; reuse emptyNodes as much as we can
1645
+ var numParams = 0;
1646
+ for (var i in data.params) numParams++;
1647
+ var emptyNodes = 0;
1648
+ while (emptyNodes < stats.length) {
1649
+ if (!isEmptyNode(stats[emptyNodes])) break;
1650
+ emptyNodes++;
1651
+ }
1652
+ var neededEmptyNodes = numParams + 1; // params plus one big var
1653
+ if (neededEmptyNodes > emptyNodes) {
1654
+ var args = [0, 0];
1655
+ for (var i = 0; i < neededEmptyNodes - emptyNodes; i++) args[i+2] = 0;
1656
+ stats.splice.apply(stats, args);
1657
+ }
1658
+ // add param coercions
1659
+ var next = 0;
1660
+ func[2].forEach(function(param) {
1661
+ stats[next++] = ['stat', ['assign', true, ['name', param], makeAsmParamCoercion(param, data.params[param])]];
1662
+ });
1663
+ // add variable definitions
1664
+ var varDefs = [];
1665
+ for (var v in data.vars) {
1666
+ varDefs.push(makeAsmVarDef(v, data.vars[v]));
1667
+ }
1668
+ if (varDefs.length) {
1669
+ stats[next] = ['var', varDefs];
1670
+ } else {
1671
+ stats[next] = emptyNode();
1672
+ }
1673
+ //printErr('denormalized \n\n' + astToSrc(func) + '\n\n');
1674
+ }
1675
+
1676
+ // Very simple 'registerization', coalescing of variables into a smaller number,
1677
+ // as part of minification. Globals-level minification began in a previous pass,
1678
+ // we receive extraInfo which tells us how to rename globals. (Only in asm.js.)
1679
+ //
1680
+ // We do not optimize when there are switches, so this pass only makes sense with
1681
+ // relooping.
1682
+ // TODO: Consider how this fits in with the rest of the optimization toolchain. Do
1683
+ // we still need the eliminator? Closure? And in what order? Perhaps just
1684
+ // closure simple?
1685
+ function registerize(ast) {
1686
+ traverseGeneratedFunctions(ast, function(fun) {
1687
+ if (asm) var asmData = normalizeAsm(fun);
1688
+ // Add parameters as a first (fake) var (with assignment), so they get taken into consideration
1689
+ var params = {}; // note: params are special, they can never share a register between them (see later)
1690
+ if (fun[2] && fun[2].length) {
1691
+ var assign = ['num', 0];
1692
+ fun[3].unshift(['var', fun[2].map(function(param) {
1693
+ params[param] = 1;
1694
+ return [param, assign];
1695
+ })]);
1696
+ }
1697
+ if (asm) {
1698
+ // copy params into vars
1699
+ for (var p in asmData.params) asmData.vars[p] = asmData.params[p];
1700
+ //printErr('fake params: \n\n' + astToSrc(fun) + '\n\n');
1701
+ }
1702
+ // Replace all var definitions with assignments; we will add var definitions at the top after we registerize
1703
+ // We also mark local variables - i.e., having a var definition
1704
+ var localVars = {};
1705
+ var hasSwitch = false; // we cannot optimize variables if there is a switch, unless in asm mode
1706
+ traverse(fun, function(node, type) {
1707
+ if (type === 'var') {
1708
+ node[1].forEach(function(defined) { localVars[defined[0]] = 1 });
1709
+ var vars = node[1].filter(function(varr) { return varr[1] });
1710
+ if (vars.length >= 1) {
1711
+ return unVarify(vars);
1712
+ } else {
1713
+ return emptyNode();
1714
+ }
1715
+ } else if (type === 'switch') {
1716
+ hasSwitch = true;
1717
+ }
1718
+ });
1719
+ vacuum(fun);
1720
+ if (extraInfo) {
1721
+ assert(asm);
1722
+ var usedGlobals = {};
1723
+ var nextLocal = 0;
1724
+ // Minify globals using the mapping we were given
1725
+ traverse(fun, function(node, type) {
1726
+ if (type === 'name') {
1727
+ var name = node[1];
1728
+ var minified = extraInfo.globals[name];
1729
+ if (minified) {
1730
+ assert(!localVars[name], name); // locals must not shadow globals, or else we don't know which is which
1731
+ if (localVars[minified]) {
1732
+ // trying to minify a global into a name used locally. rename all the locals
1733
+ var newName = '$_newLocal_' + (nextLocal++);
1734
+ assert(!localVars[newName]);
1735
+ if (params[minified]) {
1736
+ params[newName] = 1;
1737
+ delete params[minified];
1738
+ }
1739
+ localVars[newName] = 1;
1740
+ delete localVars[minified];
1741
+ asmData.vars[newName] = asmData.vars[minified];
1742
+ delete asmData.vars[minified];
1743
+ asmData.params[newName] = asmData.params[minified];
1744
+ delete asmData.params[minified];
1745
+ traverse(fun, function(node, type) {
1746
+ if (type === 'name' && node[1] === minified) {
1747
+ node[1] = newName;
1748
+ }
1749
+ });
1750
+ if (fun[2]) {
1751
+ for (var i = 0; i < fun[2].length; i++) {
1752
+ if (fun[2][i] === minified) fun[2][i] = newName;
1753
+ }
1754
+ }
1755
+ }
1756
+ node[1] = minified;
1757
+ usedGlobals[minified] = 1;
1758
+ }
1759
+ }
1760
+ });
1761
+ assert(fun[1] in extraInfo.globals, fun[1]);
1762
+ fun[1] = extraInfo.globals[fun[1]];
1763
+ assert(fun[1]);
1764
+ var nextRegName = 0;
1765
+ }
1766
+ var regTypes = {};
1767
+ function getNewRegName(num, name) {
1768
+ if (!asm) return 'r' + num;
1769
+ var type = asmData.vars[name];
1770
+ if (!extraInfo) {
1771
+ var ret = (type ? 'd' : 'i') + num;
1772
+ regTypes[ret] = type;
1773
+ return ret;
1774
+ }
1775
+ // find the next free minified name that is not used by a global that shows up in this function
1776
+ while (nextRegName < extraInfo.names.length) {
1777
+ var ret = extraInfo.names[nextRegName++];
1778
+ if (!usedGlobals[ret]) {
1779
+ regTypes[ret] = type;
1780
+ return ret;
1781
+ }
1782
+ }
1783
+ assert('ran out of names');
1784
+ }
1785
+ // Find the # of uses of each variable.
1786
+ // While doing so, check if all a variable's uses are dominated in a simple
1787
+ // way by a simple assign, if so, then we can assign its register to it
1788
+ // just for its definition to its last use, and not to the entire toplevel loop,
1789
+ // we call such variables "optimizable"
1790
+ var varUses = {};
1791
+ var level = 1;
1792
+ var levelDominations = {};
1793
+ var varLevels = {};
1794
+ var possibles = {};
1795
+ var unoptimizables = {};
1796
+ function purgeLevel() {
1797
+ // Invalidate all dominating on this level, further users make it unoptimizable
1798
+ for (var name in levelDominations[level]) {
1799
+ varLevels[name] = 0;
1800
+ }
1801
+ levelDominations[level] = null;
1802
+ level--;
1803
+ }
1804
+ traverse(fun, function possibilifier(node, type) {
1805
+ if (type === 'name') {
1806
+ var name = node[1];
1807
+ if (localVars[name]) {
1808
+ if (!varUses[name]) varUses[name] = 0;
1809
+ varUses[name]++;
1810
+ if (possibles[name] && !varLevels[name]) unoptimizables[name] = 1; // used outside of simple domination
1811
+ }
1812
+ } else if (type === 'assign' && typeof node[1] != 'string') {
1813
+ if (node[2] && node[2][0] === 'name') {
1814
+ var name = node[2][1];
1815
+ // if local and not yet used, this might be optimizable if we dominate
1816
+ // all other uses
1817
+ if (localVars[name] && !varUses[name] && !varLevels[name]) {
1818
+ possibles[name] = 1;
1819
+ varLevels[name] = level;
1820
+ if (!levelDominations[level]) levelDominations[level] = {};
1821
+ levelDominations[level][name] = 1;
1822
+ }
1823
+ }
1824
+ } else if (type in CONTROL_FLOW) {
1825
+ // recurse children, in the context of a loop
1826
+ switch(type) {
1827
+ case 'while': case 'do': {
1828
+ traverse(node[1], possibilifier);
1829
+ level++;
1830
+ traverse(node[2], possibilifier);
1831
+ purgeLevel();
1832
+ break;
1833
+ }
1834
+ case 'for': {
1835
+ traverse(node[1], possibilifier);
1836
+ for (var i = 2; i <= 4; i++) {
1837
+ level++;
1838
+ traverse(node[i], possibilifier);
1839
+ purgeLevel();
1840
+ }
1841
+ break;
1842
+ }
1843
+ case 'if': {
1844
+ traverse(node[1], possibilifier);
1845
+ level++;
1846
+ traverse(node[2], possibilifier);
1847
+ purgeLevel();
1848
+ if (node[3]) {
1849
+ level++;
1850
+ traverse(node[3], possibilifier);
1851
+ purgeLevel();
1852
+ }
1853
+ break;
1854
+ }
1855
+ case 'switch': {
1856
+ traverse(node[1], possibilifier);
1857
+ var cases = node[2];
1858
+ for (var i = 0; i < cases.length; i++) {
1859
+ level++;
1860
+ traverse(cases[i][1], possibilifier);
1861
+ purgeLevel();
1862
+ }
1863
+ break;
1864
+ }
1865
+ default: throw dumpAst(node);
1866
+ }
1867
+ return null; // prevent recursion into children, which we already did
1868
+ }
1869
+ });
1870
+ var optimizables = {};
1871
+ if (!hasSwitch || asm) {
1872
+ for (var possible in possibles) {
1873
+ if (!unoptimizables[possible]) optimizables[possible] = 1;
1874
+ }
1875
+ }
1876
+
1877
+ //printErr('optimizables: ' + JSON.stringify(optimizables));
1878
+ //printErr('unoptimizables: ' + JSON.stringify(unoptimizables));
1879
+
1880
+ // Go through the function's code, assigning 'registers'.
1881
+ // The only tricky bit is to keep variables locked on a register through loops,
1882
+ // since they can potentially be returned to. Optimizable variables lock onto
1883
+ // loops that they enter, unoptimizable variables lock in a conservative way
1884
+ // into the topmost loop.
1885
+ // Note that we cannot lock onto a variable in a loop if it was used and free'd
1886
+ // before! (then they could overwrite us in the early part of the loop). For now
1887
+ // we just use a fresh register to make sure we avoid this, but it could be
1888
+ // optimized to check for safe registers (free, and not used in this loop level).
1889
+ var varRegs = {}; // maps variables to the register they will use all their life
1890
+ var freeRegsClasses = asm ? [[], []] : []; // two classes for asm, one otherwise
1891
+ var nextReg = 1;
1892
+ var fullNames = {};
1893
+ var loopRegs = {}; // for each loop nesting level, the list of bound variables
1894
+ var loops = 0; // 0 is toplevel, 1 is first loop, etc
1895
+ var saved = 0;
1896
+ var activeOptimizables = {};
1897
+ var optimizableLoops = {};
1898
+ var paramRegs = {}; // true if the register is used by a parameter (and so needs no def at start of function; also cannot
1899
+ // be shared with another param, each needs its own)
1900
+ function decUse(name) {
1901
+ if (!varUses[name]) return false; // no uses left, or not a relevant variable
1902
+ if (optimizables[name]) activeOptimizables[name] = 1;
1903
+ var reg = varRegs[name];
1904
+ if (asm) assert(name in asmData.vars, name);
1905
+ var freeRegs = asm ? freeRegsClasses[asmData.vars[name]] : freeRegsClasses;
1906
+ if (!reg) {
1907
+ // acquire register
1908
+ if (optimizables[name] && freeRegs.length > 0 &&
1909
+ !(params[name] && paramRegs[freeRegs[freeRegs.length-1]])) { // do not share registers between parameters
1910
+ reg = freeRegs.pop();
1911
+ saved++;
1912
+ } else {
1913
+ reg = nextReg++;
1914
+ fullNames[reg] = getNewRegName(reg, name);
1915
+ if (params[name]) paramRegs[reg] = 1;
1916
+ }
1917
+ varRegs[name] = reg;
1918
+ }
1919
+ varUses[name]--;
1920
+ assert(varUses[name] >= 0);
1921
+ if (varUses[name] === 0) {
1922
+ if (optimizables[name]) delete activeOptimizables[name];
1923
+ // If we are not in a loop, or we are optimizable and not bound to a loop
1924
+ // (we might have been in one but left it), we can free the register now.
1925
+ if (loops === 0 || (optimizables[name] && !optimizableLoops[name])) {
1926
+ // free register
1927
+ freeRegs.push(reg);
1928
+ } else {
1929
+ // when the relevant loop is exited, we will free the register
1930
+ var releventLoop = optimizables[name] ? (optimizableLoops[name] || 1) : 1;
1931
+ if (!loopRegs[releventLoop]) loopRegs[releventLoop] = [];
1932
+ loopRegs[releventLoop].push(reg);
1933
+ }
1934
+ }
1935
+ return true;
1936
+ }
1937
+ traverse(fun, function(node, type) { // XXX we rely on traversal order being the same as execution order here
1938
+ if (type === 'name') {
1939
+ var name = node[1];
1940
+ if (decUse(name)) {
1941
+ node[1] = fullNames[varRegs[name]];
1942
+ }
1943
+ } else if (type in LOOP) {
1944
+ loops++;
1945
+ // Active optimizables lock onto this loop, if not locked onto one that encloses this one
1946
+ for (var name in activeOptimizables) {
1947
+ if (!optimizableLoops[name]) {
1948
+ optimizableLoops[name] = loops;
1949
+ }
1950
+ }
1951
+ }
1952
+ }, function(node, type) {
1953
+ if (type in LOOP) {
1954
+ // Free registers that were locked to this loop
1955
+ if (loopRegs[loops]) {
1956
+ if (asm) {
1957
+ loopRegs[loops].forEach(function(loopReg) {
1958
+ freeRegsClasses[regTypes[fullNames[loopReg]]].push(loopReg);
1959
+ });
1960
+ } else {
1961
+ freeRegsClasses = freeRegsClasses.concat(loopRegs[loops]);
1962
+ }
1963
+ loopRegs[loops].length = 0;
1964
+ }
1965
+ loops--;
1966
+ }
1967
+ });
1968
+ if (fun[2] && fun[2].length) {
1969
+ fun[2].length = 0; // clear params, we will fill with registers
1970
+ fun[3].shift(); // remove fake initial var
1971
+ }
1972
+ //printErr('var regs: ' + JSON.stringify(varRegs) + '\n\nparam regs: ' + JSON.stringify(paramRegs));
1973
+ if (!asm) {
1974
+ if (nextReg > 1) {
1975
+ var vars = [];
1976
+ for (var i = 1; i < nextReg; i++) {
1977
+ var reg = fullNames[i];
1978
+ if (!paramRegs[i]) {
1979
+ vars.push([reg]);
1980
+ } else {
1981
+ fun[2].push(reg);
1982
+ }
1983
+ }
1984
+ if (vars.length > 0) getStatements(fun).unshift(['var', vars]);
1985
+ }
1986
+ } else {
1987
+ //printErr('unfake params: \n\n' + astToSrc(fun) + '\n\n');
1988
+ var finalAsmData = {
1989
+ params: {},
1990
+ vars: {},
1991
+ };
1992
+ for (var i = 1; i < nextReg; i++) {
1993
+ var reg = fullNames[i];
1994
+ var type = regTypes[reg];
1995
+ if (!paramRegs[i]) {
1996
+ finalAsmData.vars[reg] = type;
1997
+ } else {
1998
+ finalAsmData.params[reg] = type;
1999
+ fun[2].push(reg);
2000
+ }
2001
+ }
2002
+ denormalizeAsm(fun, finalAsmData);
2003
+ }
2004
+ });
2005
+ }
2006
+
2007
+ // Eliminator aka Expressionizer
2008
+ //
2009
+ // The goal of this pass is to eliminate unneeded variables (which represent one of the infinite registers in the LLVM
2010
+ // model) and thus to generate complex expressions where possible, for example
2011
+ //
2012
+ // var x = a(10);
2013
+ // var y = HEAP[20];
2014
+ // print(x+y);
2015
+ //
2016
+ // can be transformed into
2017
+ //
2018
+ // print(a(10)+HEAP[20]);
2019
+ //
2020
+ // The basic principle is to scan along the code in the order of parsing/execution, and keep a list of tracked
2021
+ // variables that are current contenders for elimination. We must untrack when we see something that we cannot
2022
+ // cross, for example, a write to memory means we must invalidate variables that depend on reading from
2023
+ // memory, since if we change the order then we do not preserve the computation.
2024
+ //
2025
+ // We rely on some assumptions about emscripten-generated code here, which means we can do a lot more than
2026
+ // a general JS optimization can. For example, we assume that 'sub' nodes (indexing like HEAP[..]) are
2027
+ // memory accesses or FUNCTION_TABLE accesses, and in both cases that the symbol cannot be replaced although
2028
+ // the contents can. So we assume FUNCTION_TABLE might have its contents changed but not be pointed to
2029
+ // a different object, which allows
2030
+ //
2031
+ // var x = f();
2032
+ // FUNCTION_TABLE[x]();
2033
+ //
2034
+ // to be optimized (f could replace FUNCTION_TABLE, so in general JS eliminating x is not valid).
2035
+ //
2036
+ // In memSafe mode, we are more careful and assume functions can replace HEAP and FUNCTION_TABLE, which
2037
+ // can happen in ALLOW_MEMORY_GROWTH mode
2038
+
2039
+ var ELIMINATION_SAFE_NODES = set('var', 'assign', 'call', 'if', 'toplevel', 'do', 'return', 'label', 'switch'); // do is checked carefully, however
2040
+ var NODES_WITHOUT_ELIMINATION_SIDE_EFFECTS = set('name', 'num', 'string', 'binary', 'sub', 'unary-prefix');
2041
+ var IGNORABLE_ELIMINATOR_SCAN_NODES = set('num', 'toplevel', 'string', 'break', 'continue', 'dot'); // dot can only be STRING_TABLE.*
2042
+ var ABORTING_ELIMINATOR_SCAN_NODES = set('new', 'object', 'function', 'defun', 'for', 'while', 'array', 'throw'); // we could handle some of these, TODO, but nontrivial (e.g. for while, the condition is hit multiple times after the body)
2043
+
2044
+ function isTempDoublePtrAccess(node) { // these are used in bitcasts; they are not really affecting memory, and should cause no invalidation
2045
+ assert(node[0] === 'sub');
2046
+ return (node[2][0] === 'name' && node[2][1] === 'tempDoublePtr') ||
2047
+ (node[2][0] === 'binary' && ((node[2][2][0] === 'name' && node[2][2][1] === 'tempDoublePtr') ||
2048
+ (node[2][3][0] === 'name' && node[2][3][1] === 'tempDoublePtr')));
2049
+ }
2050
+
2051
+ function eliminate(ast, memSafe) {
2052
+ // Find variables that have a single use, and if they can be eliminated, do so
2053
+ traverseGeneratedFunctions(ast, function(func, type) {
2054
+ if (asm) var asmData = normalizeAsm(func);
2055
+ //printErr('eliminate in ' + func[1]);
2056
+
2057
+ // First, find the potentially eliminatable functions: that have one definition and one use
2058
+ var definitions = {};
2059
+ var uses = {};
2060
+ var namings = {};
2061
+ var values = {};
2062
+ var locals = {};
2063
+ var varsToRemove = {}; // variables being removed, that we can eliminate all 'var x;' of (this refers to 'var' nodes we should remove)
2064
+ // 1 means we should remove it, 2 means we successfully removed it
2065
+ var varsToTryToRemove = {}; // variables that have 0 uses, but have side effects - when we scan we can try to remove them
2066
+ // add arguments as locals
2067
+ if (func[2]) {
2068
+ for (var i = 0; i < func[2].length; i++) {
2069
+ locals[func[2][i]] = true;
2070
+ }
2071
+ }
2072
+ // examine body and note locals
2073
+ var hasSwitch = false;
2074
+ traverse(func, function(node, type) {
2075
+ if (type === 'var') {
2076
+ var node1 = node[1];
2077
+ for (var i = 0; i < node1.length; i++) {
2078
+ var node1i = node1[i];
2079
+ var name = node1i[0];
2080
+ var value = node1i[1];
2081
+ if (value) {
2082
+ if (!(name in definitions)) definitions[name] = 0;
2083
+ definitions[name]++;
2084
+ if (!values[name]) values[name] = value;
2085
+ }
2086
+ if (!uses[name]) uses[name] = 0;
2087
+ locals[name] = true;
2088
+ }
2089
+ } else if (type === 'name') {
2090
+ var name = node[1];
2091
+ if (!uses[name]) uses[name] = 0;
2092
+ uses[name]++;
2093
+ } else if (type === 'assign') {
2094
+ var target = node[2];
2095
+ if (target[0] === 'name') {
2096
+ var name = target[1];
2097
+ if (!(name in definitions)) definitions[name] = 0;
2098
+ definitions[name]++;
2099
+ if (!uses[name]) uses[name] = 0;
2100
+ if (!values[name]) values[name] = node[3];
2101
+ if (node[1] === true) { // not +=, -= etc., just =
2102
+ uses[name]--; // because the name node will show up by itself in the previous case
2103
+ if (!namings[name]) namings[name] = 0;
2104
+ namings[name]++; // offset it here, this tracks the total times we are named
2105
+ }
2106
+ }
2107
+ } else if (type === 'switch') {
2108
+ hasSwitch = true;
2109
+ }
2110
+ });
2111
+
2112
+ for (var used in uses) {
2113
+ namings[used] = (namings[used] || 0) + uses[used];
2114
+ }
2115
+
2116
+ // we cannot eliminate variables if there is a switch
2117
+ if (hasSwitch && !asm) return;
2118
+
2119
+ var potentials = {}; // local variables with 1 definition and 1 use
2120
+ var sideEffectFree = {}; // whether a local variable has no side effects in its definition. Only relevant when there are no uses
2121
+
2122
+ function unprocessVariable(name) {
2123
+ if (name in potentials) delete potentials[name];
2124
+ if (name in varsToRemove) delete varsToRemove[name];
2125
+ if (name in sideEffectFree) delete sideEffectFree[name];
2126
+ if (name in varsToTryToRemove) delete varsToTryToRemove[name];
2127
+ }
2128
+ function processVariable(name) {
2129
+ if (definitions[name] === 1 && uses[name] === 1) {
2130
+ potentials[name] = 1;
2131
+ } else if (uses[name] === 0 && (!definitions[name] || definitions[name] <= 1)) { // no uses, no def or 1 def (cannot operate on phis, and the llvm optimizer will remove unneeded phis anyhow) (no definition means it is a function parameter, or a local with just |var x;| but no defining assignment)
2132
+ var hasSideEffects = false;
2133
+ var value = values[name];
2134
+ if (value) {
2135
+ // TODO: merge with other side effect code
2136
+ // First, pattern-match
2137
+ // (HEAP32[((tempDoublePtr)>>2)]=((HEAP32[(($_sroa_0_0__idx1)>>2)])|0),HEAP32[(((tempDoublePtr)+(4))>>2)]=((HEAP32[((($_sroa_0_0__idx1)+(4))>>2)])|0),(+(HEAPF64[(tempDoublePtr)>>3])))
2138
+ // which has no side effects and is the special form of converting double to i64.
2139
+ if (!(value[0] === 'seq' && value[1][0] === 'assign' && value[1][2][0] === 'sub' && value[1][2][2][0] === 'binary' && value[1][2][2][1] === '>>' &&
2140
+ value[1][2][2][2][0] === 'name' && value[1][2][2][2][1] === 'tempDoublePtr')) {
2141
+ // If not that, then traverse and scan normally.
2142
+ traverse(value, function(node, type) {
2143
+ if (!(type in NODES_WITHOUT_ELIMINATION_SIDE_EFFECTS)) {
2144
+ hasSideEffects = true; // cannot remove this unused variable, constructing it has side effects
2145
+ return true;
2146
+ }
2147
+ });
2148
+ }
2149
+ }
2150
+ if (!hasSideEffects) {
2151
+ varsToRemove[name] = !definitions[name] ? 2 : 1; // remove it normally
2152
+ sideEffectFree[name] = true;
2153
+ // Each time we remove a variable with 0 uses, if its value has no
2154
+ // side effects and vanishes too, then we can remove a use from variables
2155
+ // appearing in it, and possibly eliminate again
2156
+ if (value) {
2157
+ traverse(value, function(node, type) {
2158
+ if (type === 'name') {
2159
+ var name = node[1];
2160
+ node[1] = ''; // we can remove this - it will never be shown, and should not be left to confuse us as we traverse
2161
+ if (name in locals) {
2162
+ uses[name]--; // cannot be infinite recursion since we descend an energy function
2163
+ assert(uses[name] >= 0);
2164
+ unprocessVariable(name);
2165
+ processVariable(name);
2166
+ }
2167
+ }
2168
+ });
2169
+ }
2170
+ } else {
2171
+ varsToTryToRemove[name] = 1; // try to remove it later during scanning
2172
+ }
2173
+ }
2174
+ }
2175
+ for (var name in locals) {
2176
+ processVariable(name);
2177
+ }
2178
+
2179
+ //printErr('defs: ' + JSON.stringify(definitions));
2180
+ //printErr('uses: ' + JSON.stringify(uses));
2181
+ //printErr('values: ' + JSON.stringify(values));
2182
+ //printErr('locals: ' + JSON.stringify(locals));
2183
+ //printErr('varsToRemove: ' + JSON.stringify(varsToRemove));
2184
+ //printErr('varsToTryToRemove: ' + JSON.stringify(varsToTryToRemove));
2185
+ values = null;
2186
+ //printErr('potentials: ' + JSON.stringify(potentials));
2187
+ // We can now proceed through the function. In each list of statements, we try to eliminate
2188
+ var tracked = {};
2189
+ var globalsInvalidated = false; // do not repeat invalidations, until we track something new
2190
+ var memoryInvalidated = false;
2191
+ var callsInvalidated = false;
2192
+ function track(name, value, defNode) { // add a potential that has just been defined to the tracked list, we hope to eliminate it
2193
+ var usesGlobals = false, usesMemory = false, deps = {}, doesCall = false;
2194
+ var ignoreName = false; // one-time ignorings of names, as first op in sub and call
2195
+ traverse(value, function(node, type) {
2196
+ if (type === 'name') {
2197
+ if (!ignoreName) {
2198
+ var name = node[1];
2199
+ if (!(name in locals)) {
2200
+ usesGlobals = true;
2201
+ }
2202
+ if (!(name in potentials)) { // deps do not matter for potentials - they are defined once, so no complexity
2203
+ deps[name] = 1;
2204
+ }
2205
+ } else {
2206
+ ignoreName = false;
2207
+ }
2208
+ } else if (type === 'sub') {
2209
+ usesMemory = true;
2210
+ ignoreName = true;
2211
+ } else if (type === 'call') {
2212
+ usesGlobals = true;
2213
+ usesMemory = true;
2214
+ doesCall = true;
2215
+ ignoreName = true;
2216
+ } else {
2217
+ ignoreName = false;
2218
+ }
2219
+ });
2220
+ tracked[name] = {
2221
+ usesGlobals: usesGlobals,
2222
+ usesMemory: usesMemory,
2223
+ defNode: defNode,
2224
+ deps: deps,
2225
+ doesCall: doesCall
2226
+ };
2227
+ globalsInvalidated = false;
2228
+ memoryInvalidated = false;
2229
+ callsInvalidated = false;
2230
+ //printErr('track ' + [name, JSON.stringify(tracked[name])]);
2231
+ }
2232
+ var temp = [];
2233
+ // TODO: invalidate using a sequence number for each type (if you were tracked before the last invalidation, you are cancelled). remove for.in loops
2234
+ function invalidateGlobals() {
2235
+ //printErr('invalidate globals');
2236
+ temp.length = 0;
2237
+ for (var name in tracked) {
2238
+ var info = tracked[name];
2239
+ if (info.usesGlobals) {
2240
+ temp.push(name);
2241
+ }
2242
+ }
2243
+ for (var i = 0; i < temp.length; i++) {
2244
+ delete tracked[temp[i]];
2245
+ }
2246
+ }
2247
+ function invalidateMemory() {
2248
+ //printErr('invalidate memory');
2249
+ temp.length = 0;
2250
+ for (var name in tracked) {
2251
+ var info = tracked[name];
2252
+ if (info.usesMemory) {
2253
+ temp.push(name);
2254
+ }
2255
+ }
2256
+ for (var i = 0; i < temp.length; i++) {
2257
+ delete tracked[temp[i]];
2258
+ }
2259
+ }
2260
+ function invalidateByDep(dep) {
2261
+ //printErr('invalidate by dep ' + dep);
2262
+ temp.length = 0;
2263
+ for (var name in tracked) {
2264
+ var info = tracked[name];
2265
+ if (info.deps[dep]) {
2266
+ temp.push(name);
2267
+ }
2268
+ }
2269
+ for (var i = 0; i < temp.length; i++) {
2270
+ delete tracked[temp[i]];
2271
+ }
2272
+ }
2273
+ function invalidateCalls() {
2274
+ //printErr('invalidate calls');
2275
+ temp.length = 0;
2276
+ for (var name in tracked) {
2277
+ var info = tracked[name];
2278
+ if (info.doesCall) {
2279
+ temp.push(name);
2280
+ }
2281
+ }
2282
+ for (var i = 0; i < temp.length; i++) {
2283
+ delete tracked[temp[i]];
2284
+ }
2285
+ }
2286
+
2287
+ // Generate the sequence of execution. This determines what is executed before what, so we know what can be reordered. Using
2288
+ // that, performs invalidations and eliminations
2289
+ function scan(node) {
2290
+ //printErr('scan: ' + JSON.stringify(node).substr(0, 50) + ' : ' + keys(tracked));
2291
+ var abort = false;
2292
+ var allowTracking = true; // false inside an if; also prevents recursing in an if
2293
+ //var nesting = 1; // printErr-related
2294
+ function traverseInOrder(node, ignoreSub, ignoreName) {
2295
+ if (abort) return;
2296
+ //nesting++; // printErr-related
2297
+ //printErr(spaces(2*(nesting+1)) + 'trav: ' + JSON.stringify(node).substr(0, 50) + ' : ' + keys(tracked) + ' : ' + [allowTracking, ignoreSub, ignoreName]);
2298
+ var type = node[0];
2299
+ if (type === 'assign') {
2300
+ var target = node[2];
2301
+ var value = node[3];
2302
+ var nameTarget = target[0] === 'name';
2303
+ traverseInOrder(target, true, nameTarget); // evaluate left
2304
+ traverseInOrder(value); // evaluate right
2305
+ // do the actual assignment
2306
+ if (nameTarget) {
2307
+ var name = target[1];
2308
+ if (!(name in potentials)) {
2309
+ if (!(name in varsToTryToRemove)) {
2310
+ // expensive check for invalidating specific tracked vars. This list is generally quite short though, because of
2311
+ // how we just eliminate in short spans and abort when control flow happens TODO: history numbers instead
2312
+ invalidateByDep(name); // can happen more than once per dep..
2313
+ if (!(name in locals) && !globalsInvalidated) {
2314
+ invalidateGlobals();
2315
+ globalsInvalidated = true;
2316
+ }
2317
+ // if we can track this name (that we assign into), and it has 0 uses and we want to remove its 'var'
2318
+ // definition - then remove it right now, there is no later chance
2319
+ if (allowTracking && (name in varsToRemove) && uses[name] === 0) {
2320
+ track(name, node[3], node);
2321
+ doEliminate(name, node);
2322
+ }
2323
+ } else {
2324
+ // replace it in-place
2325
+ node.length = value.length;
2326
+ for (var i = 0; i < value.length; i++) {
2327
+ node[i] = value[i];
2328
+ }
2329
+ varsToRemove[name] = 2;
2330
+ }
2331
+ } else {
2332
+ if (allowTracking) track(name, node[3], node);
2333
+ }
2334
+ } else if (target[0] === 'sub') {
2335
+ if (!isTempDoublePtrAccess(target) && !memoryInvalidated) {
2336
+ invalidateMemory();
2337
+ memoryInvalidated = true;
2338
+ }
2339
+ }
2340
+ } else if (type === 'sub') {
2341
+ traverseInOrder(node[1], false, !memSafe); // evaluate inner
2342
+ traverseInOrder(node[2]); // evaluate outer
2343
+ // ignoreSub means we are a write (happening later), not a read
2344
+ if (!ignoreSub && !isTempDoublePtrAccess(node)) {
2345
+ // do the memory access
2346
+ if (!callsInvalidated) {
2347
+ invalidateCalls();
2348
+ callsInvalidated = true;
2349
+ }
2350
+ }
2351
+ } else if (type === 'var') {
2352
+ var vars = node[1];
2353
+ for (var i = 0; i < vars.length; i++) {
2354
+ var name = vars[i][0];
2355
+ var value = vars[i][1];
2356
+ if (value) {
2357
+ traverseInOrder(value);
2358
+ if (name in potentials && allowTracking) {
2359
+ track(name, value, node);
2360
+ } else {
2361
+ invalidateByDep(name);
2362
+ }
2363
+ if (vars.length === 1 && name in varsToTryToRemove && value) {
2364
+ // replace it in-place
2365
+ value = ['stat', value];
2366
+ node.length = value.length;
2367
+ for (var i = 0; i < value.length; i++) {
2368
+ node[i] = value[i];
2369
+ }
2370
+ varsToRemove[name] = 2;
2371
+ }
2372
+ }
2373
+ }
2374
+ } else if (type === 'binary') {
2375
+ var flipped = false;
2376
+ if (node[1] in ASSOCIATIVE_BINARIES && !(node[2][0] in NAME_OR_NUM) && node[3][0] in NAME_OR_NUM) { // TODO recurse here?
2377
+ // associatives like + and * can be reordered in the simple case of one of the sides being a name, since we assume they are all just numbers
2378
+ var temp = node[2];
2379
+ node[2] = node[3];
2380
+ node[3] = temp;
2381
+ flipped = true;
2382
+ }
2383
+ traverseInOrder(node[2]);
2384
+ traverseInOrder(node[3]);
2385
+ if (flipped && node[2][0] in NAME_OR_NUM) { // dunno if we optimized, but safe to flip back - and keeps the code closer to the original and more readable
2386
+ var temp = node[2];
2387
+ node[2] = node[3];
2388
+ node[3] = temp;
2389
+ }
2390
+ } else if (type === 'name') {
2391
+ if (!ignoreName) { // ignoreName means we are the name of something like a call or a sub - irrelevant for us
2392
+ var name = node[1];
2393
+ if (name in tracked) {
2394
+ doEliminate(name, node);
2395
+ } else if (!(name in locals) && !callsInvalidated) {
2396
+ invalidateCalls();
2397
+ callsInvalidated = true;
2398
+ }
2399
+ }
2400
+ } else if (type === 'unary-prefix' || type === 'unary-postfix') {
2401
+ traverseInOrder(node[2]);
2402
+ } else if (type in IGNORABLE_ELIMINATOR_SCAN_NODES) {
2403
+ } else if (type === 'call') {
2404
+ traverseInOrder(node[1], false, true);
2405
+ var args = node[2];
2406
+ for (var i = 0; i < args.length; i++) {
2407
+ traverseInOrder(args[i]);
2408
+ }
2409
+ // these two invalidations will also invalidate calls
2410
+ if (!globalsInvalidated) {
2411
+ invalidateGlobals();
2412
+ globalsInvalidated = true;
2413
+ }
2414
+ if (!memoryInvalidated) {
2415
+ invalidateMemory();
2416
+ memoryInvalidated = true;
2417
+ }
2418
+ } else if (type === 'if') {
2419
+ if (allowTracking) {
2420
+ traverseInOrder(node[1]); // can eliminate into condition, but nowhere else
2421
+ if (!callsInvalidated) { // invalidate calls, since we cannot eliminate them into an if that may not execute!
2422
+ invalidateCalls();
2423
+ callsInvalidated = true;
2424
+ }
2425
+
2426
+ allowTracking = false;
2427
+ traverseInOrder(node[2]); // 2 and 3 could be 'parallel', really..
2428
+ if (node[3]) traverseInOrder(node[3]);
2429
+ allowTracking = true;
2430
+
2431
+ } else {
2432
+ tracked = {};
2433
+ }
2434
+ } else if (type === 'block') {
2435
+ var stats = node[1];
2436
+ if (stats) {
2437
+ for (var i = 0; i < stats.length; i++) {
2438
+ traverseInOrder(stats[i]);
2439
+ }
2440
+ }
2441
+ } else if (type === 'stat') {
2442
+ traverseInOrder(node[1]);
2443
+ } else if (type === 'label') {
2444
+ traverseInOrder(node[2]);
2445
+ } else if (type === 'seq') {
2446
+ traverseInOrder(node[1]);
2447
+ traverseInOrder(node[2]);
2448
+ } else if (type === 'do') {
2449
+ if (node[1][0] === 'num' && node[1][1] === 0) { // one-time loop
2450
+ traverseInOrder(node[2]);
2451
+ } else {
2452
+ tracked = {};
2453
+ }
2454
+ } else if (type === 'return') {
2455
+ if (node[1]) traverseInOrder(node[1]);
2456
+ } else if (type === 'conditional') {
2457
+ traverseInOrder(node[1]);
2458
+ traverseInOrder(node[2]);
2459
+ traverseInOrder(node[3]);
2460
+ } else if (type === 'switch') {
2461
+ traverseInOrder(node[1]);
2462
+ var cases = node[2];
2463
+ for (var i = 0; i < cases.length; i++) {
2464
+ var c = cases[i];
2465
+ assert(c[0] === null || c[0][0] === 'num' || (c[0][0] === 'unary-prefix' && c[0][2][0] === 'num'));
2466
+ var stats = c[1];
2467
+ for (var j = 0; j < stats.length; j++) {
2468
+ traverseInOrder(stats[j]);
2469
+ }
2470
+ }
2471
+ } else {
2472
+ if (!(type in ABORTING_ELIMINATOR_SCAN_NODES)) {
2473
+ printErr('unfamiliar eliminator scan node: ' + JSON.stringify(node));
2474
+ }
2475
+ tracked = {};
2476
+ abort = true;
2477
+ }
2478
+ //nesting--; // printErr-related
2479
+ }
2480
+ traverseInOrder(node);
2481
+ }
2482
+ //var eliminationLimit = 0; // used to debugging purposes
2483
+ function doEliminate(name, node) {
2484
+ //if (eliminationLimit === 0) return;
2485
+ //eliminationLimit--;
2486
+ //printErr('elim!!!!! ' + name);
2487
+ // yes, eliminate!
2488
+ varsToRemove[name] = 2; // both assign and var definitions can have other vars we must clean up
2489
+ var info = tracked[name];
2490
+ delete tracked[name];
2491
+ var defNode = info.defNode;
2492
+ if (!sideEffectFree[name]) {
2493
+ if (defNode[0] === 'var') {
2494
+ defNode[1].forEach(function(pair) {
2495
+ if (pair[0] === name) {
2496
+ value = pair[1];
2497
+ }
2498
+ });
2499
+ assert(value);
2500
+ } else { // assign
2501
+ value = defNode[3];
2502
+ // wipe out the assign
2503
+ defNode[0] = 'toplevel';
2504
+ defNode[1] = [];
2505
+ defNode.length = 2;
2506
+ }
2507
+ // replace this node in-place
2508
+ node.length = 0;
2509
+ for (var i = 0; i < value.length; i++) {
2510
+ node[i] = value[i];
2511
+ }
2512
+ } else {
2513
+ // This has no side effects and no uses, empty it out in-place
2514
+ node.length = 0;
2515
+ node[0] = 'toplevel';
2516
+ node[1] = [];
2517
+ }
2518
+ }
2519
+ traverse(func, function(block) {
2520
+ // Look for statements, including while-switch pattern
2521
+ var stats = getStatements(block) || (block[0] === 'while' && block[2][0] === 'switch' ? [block[2]] : stats);
2522
+ if (!stats) return;
2523
+ //printErr('Stats: ' + JSON.stringify(stats).substr(0,100));
2524
+ tracked = {};
2525
+ //printErr('new StatBlock');
2526
+ for (var i = 0; i < stats.length; i++) {
2527
+ var node = stats[i];
2528
+ //printErr('StatBlock[' + i + '] => ' + JSON.stringify(node).substr(0,100));
2529
+ var type = node[0];
2530
+ if (type === 'stat') {
2531
+ node = node[1];
2532
+ type = node[0];
2533
+ } else if (type == 'return' && i < stats.length-1) {
2534
+ stats.length = i+1; // remove any code after a return
2535
+ }
2536
+ // Check for things that affect elimination
2537
+ if (type in ELIMINATION_SAFE_NODES) {
2538
+ scan(node);
2539
+ } else {
2540
+ tracked = {}; // not a var or assign, break all potential elimination so far
2541
+ }
2542
+ }
2543
+ //printErr('delete StatBlock');
2544
+ });
2545
+
2546
+ var seenUses = {}, helperReplacements = {}; // for looper-helper optimization
2547
+
2548
+ // clean up vars, and loop variable elimination
2549
+ traverse(func, function(node, type) {
2550
+ // pre
2551
+ if (type === 'var') {
2552
+ node[1] = node[1].filter(function(pair) { return !varsToRemove[pair[0]] });
2553
+ if (node[1].length === 0) {
2554
+ // wipe out an empty |var;|
2555
+ node[0] = 'toplevel';
2556
+ node[1] = [];
2557
+ }
2558
+ }
2559
+ }, function(node, type) {
2560
+ // post
2561
+ if (type === 'name') {
2562
+ var name = node[1];
2563
+ if (name in helperReplacements) {
2564
+ node[1] = helperReplacements[name];
2565
+ return; // no need to track this anymore, we can't loop-optimize more than once
2566
+ }
2567
+ // track how many uses we saw. we need to know when a variable is no longer used (hence we run this in the post)
2568
+ if (!(name in seenUses)) {
2569
+ seenUses[name] = 1;
2570
+ } else {
2571
+ seenUses[name]++;
2572
+ }
2573
+ } else if (type === 'while') {
2574
+ // try to remove loop helper variables specifically
2575
+ var stats = node[2][1];
2576
+ var last = stats[stats.length-1];
2577
+ if (last && last[0] === 'if' && last[2][0] === 'block' && last[3] && last[3][0] === 'block') {
2578
+ var ifTrue = last[2];
2579
+ var ifFalse = last[3];
2580
+ var flip = false;
2581
+ if (ifFalse[1][0] && ifFalse[1][0][0] === 'break') { // canonicalize break in the if
2582
+ var temp = ifFalse;
2583
+ ifFalse = ifTrue;
2584
+ ifTrue = temp;
2585
+ flip = true;
2586
+ }
2587
+ if (ifTrue[1][0] && ifTrue[1][0][0] === 'break') {
2588
+ var assigns = ifFalse[1];
2589
+ var loopers = [], helpers = [];
2590
+ for (var i = 0; i < assigns.length; i++) {
2591
+ if (assigns[i][0] === 'stat' && assigns[i][1][0] === 'assign') {
2592
+ var assign = assigns[i][1];
2593
+ if (assign[1] === true && assign[2][0] === 'name' && assign[3][0] === 'name') {
2594
+ var looper = assign[2][1];
2595
+ var helper = assign[3][1];
2596
+ if (definitions[helper] === 1 && seenUses[looper] === namings[looper] &&
2597
+ !helperReplacements[helper] && !helperReplacements[looper]) {
2598
+ loopers.push(looper);
2599
+ helpers.push(helper);
2600
+ }
2601
+ }
2602
+ }
2603
+ }
2604
+ if (loopers.length < assigns.length) return; // TODO: handle the case where can can just eliminate one. (we can't optimize the break, but we can remove the var at least)
2605
+ for (var l = 0; l < loopers.length; l++) {
2606
+ var looper = loopers[l];
2607
+ var helper = helpers[l];
2608
+ // the remaining issue is whether loopers are used after the assignment to helper and before the last line (where we assign to it)
2609
+ var found = -1;
2610
+ for (var i = stats.length-2; i >= 0; i--) {
2611
+ var curr = stats[i];
2612
+ if (curr[0] === 'stat' && curr[1][0] === 'assign') {
2613
+ var currAssign = curr[1];
2614
+ if (currAssign[1] === true && currAssign[2][0] === 'name') {
2615
+ var to = currAssign[2][1];
2616
+ if (to === helper) {
2617
+ found = i;
2618
+ break;
2619
+ }
2620
+ }
2621
+ }
2622
+ }
2623
+ if (found < 0) return;
2624
+ var looperUsed = false;
2625
+ for (var i = found+1; i < stats.length && !looperUsed; i++) {
2626
+ var curr = i < stats.length-1 ? stats[i] : last[1]; // on the last line, just look in the condition
2627
+ traverse(curr, function(node, type) {
2628
+ if (type === 'name' && node[1] === looper) {
2629
+ looperUsed = true;
2630
+ return true;
2631
+ }
2632
+ });
2633
+ }
2634
+ if (looperUsed) return;
2635
+ }
2636
+ for (var l = 0; l < helpers.length; l++) {
2637
+ for (var k = 0; k < helpers.length; k++) {
2638
+ if (l != k && helpers[l] === helpers[k]) return; // it is complicated to handle a shared helper, abort
2639
+ }
2640
+ }
2641
+ // hurrah! this is safe to do
2642
+ //printErr("ELIM LOOP VAR " + JSON.stringify(loopers) + ' :: ' + JSON.stringify(helpers));
2643
+ for (var l = 0; l < loopers.length; l++) {
2644
+ var looper = loopers[l];
2645
+ var helper = helpers[l];
2646
+ varsToRemove[helper] = 2;
2647
+ traverse(node, function(node, type) { // replace all appearances of helper with looper
2648
+ if (type === 'name' && node[1] === helper) node[1] = looper;
2649
+ });
2650
+ helperReplacements[helper] = looper; // replace all future appearances of helper with looper
2651
+ helperReplacements[looper] = looper; // avoid any further attempts to optimize looper in this manner (seenUses is wrong anyhow, too)
2652
+ }
2653
+ // simplify the if. we remove the if branch, leaving only the else
2654
+ if (flip) {
2655
+ last[1] = simplifyNotCompsDirect(['unary-prefix', '!', last[1]]);
2656
+ last[2] = last[3];
2657
+ }
2658
+ last.pop();
2659
+ }
2660
+ }
2661
+ }
2662
+ });
2663
+
2664
+ if (asm) {
2665
+ for (var v in varsToRemove) {
2666
+ if (varsToRemove[v] === 2) delete asmData.vars[v];
2667
+ }
2668
+ denormalizeAsm(func, asmData);
2669
+ }
2670
+ });
2671
+
2672
+ if (!asm) { // TODO: deprecate in non-asm too
2673
+ // A class for optimizing expressions. We know that it is legitimate to collapse
2674
+ // 5+7 in the generated code, as it will always be numerical, for example. XXX do we need this? here?
2675
+ function ExpressionOptimizer(node) {
2676
+ this.node = node;
2677
+
2678
+ this.run = function() {
2679
+ traverse(this.node, function(node, type) {
2680
+ if (type === 'binary' && node[1] === '+') {
2681
+ var names = [];
2682
+ var num = 0;
2683
+ var has_num = false;
2684
+ var fail = false;
2685
+ traverse(node, function(subNode, subType) {
2686
+ if (subType === 'binary') {
2687
+ if (subNode[1] !== '+') {
2688
+ fail = true;
2689
+ return false;
2690
+ }
2691
+ } else if (subType === 'name') {
2692
+ names.push(subNode[1]);
2693
+ return;
2694
+ } else if (subType === 'num') {
2695
+ num += subNode[1];
2696
+ has_num = true;
2697
+ return;
2698
+ } else {
2699
+ fail = true;
2700
+ return false;
2701
+ }
2702
+ });
2703
+ if (!fail && has_num) {
2704
+ var ret = ['num', num];
2705
+ for (var i = 0; i < names.length; i++) {
2706
+ ret = ['binary', '+', ['name', names[i]], ret];
2707
+ }
2708
+ return ret;
2709
+ }
2710
+ }
2711
+ });
2712
+ };
2713
+ }
2714
+ new ExpressionOptimizer(ast).run();
2715
+ }
2716
+ }
2717
+
2718
+ function eliminateMemSafe(ast) {
2719
+ eliminate(ast, true);
2720
+ }
2721
+
2722
+ function minifyGlobals(ast) {
2723
+ var minified = {};
2724
+ var next = 0;
2725
+ var first = true; // do not minify initial 'var asm ='
2726
+ // find the globals
2727
+ traverse(ast, function(node, type) {
2728
+ if (type === 'var') {
2729
+ if (first) {
2730
+ first = false;
2731
+ return;
2732
+ }
2733
+ var vars = node[1];
2734
+ for (var i = 0; i < vars.length; i++) {
2735
+ var name = vars[i][0];
2736
+ assert(next < extraInfo.names.length);
2737
+ vars[i][0] = minified[name] = extraInfo.names[next++];
2738
+ }
2739
+ }
2740
+ });
2741
+ // add all globals in function chunks, i.e. not here but passed to us
2742
+ for (var i = 0; i < extraInfo.globals.length; i++) {
2743
+ name = extraInfo.globals[i];
2744
+ assert(next < extraInfo.names.length);
2745
+ minified[name] = extraInfo.names[next++];
2746
+ }
2747
+ // apply minification
2748
+ traverse(ast, function(node, type) {
2749
+ if (type === 'name') {
2750
+ var name = node[1];
2751
+ if (name in minified) {
2752
+ node[1] = minified[name];
2753
+ }
2754
+ }
2755
+ });
2756
+ suffix = '// EXTRA_INFO:' + JSON.stringify(minified);
2757
+ }
2758
+
2759
+ // Relocation pass for a shared module (for the functions part of the module)
2760
+ //
2761
+ // 1. Replace function names with alternate names as defined (to avoid colliding with
2762
+ // names in the main module we are being linked to)
2763
+ // 2. Hardcode function table offsets from F_BASE+x to const+x if x is a variable, or
2764
+ // the constant sum of the base + offset
2765
+ // 3. Hardcode heap offsets from H_BASE as well
2766
+ function relocate(ast) {
2767
+ assert(asm); // we also assume we are normalized
2768
+
2769
+ var replacements = extraInfo.replacements;
2770
+ var fBases = extraInfo.fBases;
2771
+ var hBase = extraInfo.hBase;
2772
+ var m;
2773
+
2774
+ traverse(ast, function(node, type) {
2775
+ switch(type) {
2776
+ case 'name': case 'defun': {
2777
+ var rep = replacements[node[1]];
2778
+ if (rep) node[1] = rep;
2779
+ break;
2780
+ }
2781
+ case 'binary': {
2782
+ if (node[1] == '+' && node[2][0] == 'name') {
2783
+ var base = null;
2784
+ if (node[2][1] == 'H_BASE') {
2785
+ base = hBase;
2786
+ } else if (m = /^F_BASE_(\w+)$/.exec(node[2][1])) {
2787
+ base = fBases[m[1]] || 0; // 0 if the parent has no function table for this, but the child does. so no relocation needed
2788
+ }
2789
+ if (base !== null) {
2790
+ var other = node[3];
2791
+ if (base === 0) return other;
2792
+ if (other[0] == 'num') {
2793
+ other[1] += base;
2794
+ return other;
2795
+ } else {
2796
+ node[2] = ['num', base];
2797
+ }
2798
+ }
2799
+ }
2800
+ break;
2801
+ }
2802
+ case 'var': {
2803
+ var vars = node[1];
2804
+ for (var i = 0; i < vars.length; i++) {
2805
+ var name = vars[i][0];
2806
+ assert(!(name in replacements)); // cannot shadow functions we are replacing TODO: fix that
2807
+ }
2808
+ break;
2809
+ }
2810
+ }
2811
+ });
2812
+ }
2813
+
2814
+ // Break up very large functions
2815
+
2816
+ var NODES_WITHOUT_ELIMINATION_SENSITIVITY = set('name', 'num', 'binary', 'unary-prefix');
2817
+ var FAST_ELIMINATION_BINARIES = setUnion(setUnion(USEFUL_BINARY_OPS, COMPARE_OPS), set('+'));
2818
+
2819
+ function outline(ast) {
2820
+ function measureSize(ast) {
2821
+ var size = 0;
2822
+ traverse(ast, function() {
2823
+ size++;
2824
+ });
2825
+ return size;
2826
+ }
2827
+
2828
+ function aggressiveVariableElimination(func, asmData) {
2829
+ // This removes as many variables as possible. This is often not the best thing because it increases
2830
+ // code size, but it is far preferable to the risk of split functions needing to do more spilling. Specifically,
2831
+ // it finds 'trivial' variables: ones with 1 definition, and that definition is not sensitive to any changes: it
2832
+ // only depends on constants and local variables that are themselves trivial. We can unquestionably eliminate
2833
+ // such variables in a trivial manner.
2834
+
2835
+ var assignments = {};
2836
+ var appearances = {};
2837
+ var defs = {};
2838
+ var considered = {};
2839
+
2840
+ traverse(func, function(node, type) {
2841
+ if (type == 'assign' && node[2][0] == 'name') {
2842
+ var name = node[2][1];
2843
+ if (name in asmData.vars) {
2844
+ assignments[name] = (assignments[name] || 0) + 1;
2845
+ appearances[name] = (appearances[name] || 0) - 1; // this appearance is a definition, offset the counting later
2846
+ defs[name] = node;
2847
+ } else {
2848
+ if (name in asmData.params) {
2849
+ considered[name] = true; // this parameter is not ssa, it must be in a hand-optimized function, so it is not trivial
2850
+ }
2851
+ }
2852
+ } else if (type == 'name') {
2853
+ var name = node[1];
2854
+ if (name in asmData.vars) {
2855
+ appearances[name] = (appearances[name] || 0) + 1;
2856
+ }
2857
+ }
2858
+ });
2859
+
2860
+ var allTrivials = {}; // key of a trivial var => size of its (expanded) value, at least 1
2861
+
2862
+ // three levels of variables:
2863
+ // 1. trivial: 1 def (or less), uses nothing sensitive, can be eliminated
2864
+ // 2. safe: 1 def (or less), can be used in a trivial, but cannot itself be eliminated
2865
+ // 3. sensitive: uses a global or memory or something else that prevents trivial elimination.
2866
+
2867
+ function assessTriviality(name) {
2868
+ // only care about vars with 0-1 assignments of (0 for parameters), and can ignore label (which is not explicitly initialized, but cannot be eliminated ever anyhow)
2869
+ if (assignments[name] > 1 || (!(name in asmData.vars) && !(name in asmData.params)) || name == 'label') return false;
2870
+ if (considered[name]) return allTrivials[name];
2871
+ considered[name] = true;
2872
+ var sensitive = false;
2873
+ var size = 0, originalSize = 0;
2874
+ var def = defs[name];
2875
+ if (def) {
2876
+ var value = def[3];
2877
+ originalSize = measureSize(value);
2878
+ if (value) {
2879
+ traverse(value, function recurseValue(node, type) {
2880
+ var one = node[1];
2881
+ if (!(type in NODES_WITHOUT_ELIMINATION_SENSITIVITY)) { // || (type == 'binary' && !(one in FAST_ELIMINATION_BINARIES))) {
2882
+ sensitive = true;
2883
+ return true;
2884
+ }
2885
+ if (type == 'name' && !assessTriviality(one)) {
2886
+ if (assignments[one] > 1 || (!(one in asmData.vars) && !(one in asmData.params))) {
2887
+ sensitive = true; // directly using something sensitive
2888
+ return true;
2889
+ } // otherwise, not trivial, but at least safe.
2890
+ }
2891
+ // if this is a name, it must be a trivial variable (or a safe one) and we know its size
2892
+ size += ((type == 'name') ? allTrivials[one] : 1) || 1;
2893
+ });
2894
+ }
2895
+ }
2896
+ if (!sensitive) {
2897
+ size = size || 1;
2898
+ originalSize = originalSize || 1;
2899
+ var factor = ((appearances[name] - 1) || 0) * (size - originalSize); // If no size change or just one appearance, always ok to trivially eliminate. otherwise, tradeoff
2900
+ if (factor <= 12) {
2901
+ allTrivials[name] = size; // trivial!
2902
+ return true;
2903
+ }
2904
+ }
2905
+ return false;
2906
+ }
2907
+ for (var name in asmData.vars) {
2908
+ assessTriviality(name);
2909
+ }
2910
+ var trivials = {};
2911
+
2912
+ for (var name in allTrivials) { // from now on, ignore parameters
2913
+ if (name in asmData.vars) trivials[name] = true;
2914
+ }
2915
+
2916
+ allTrivials = {};
2917
+
2918
+ var values = {};
2919
+
2920
+ function evaluate(name) {
2921
+ var node = values[name];
2922
+ if (node) return node;
2923
+ values[node] = null; // prevent infinite recursion
2924
+ var def = defs[name];
2925
+ if (def) {
2926
+ node = def[3];
2927
+ if (node[0] == 'name') {
2928
+ var name2 = node[1];
2929
+ if (name2 in trivials) {
2930
+ node = evaluate(name2);
2931
+ }
2932
+ } else {
2933
+ traverse(node, function(node, type) {
2934
+ if (type == 'name') {
2935
+ var name2 = node[1];
2936
+ if (name2 in trivials) {
2937
+ return evaluate(name2);
2938
+ }
2939
+ }
2940
+ });
2941
+ }
2942
+ values[name] = node;
2943
+ }
2944
+ return node;
2945
+ }
2946
+
2947
+ for (var name in trivials) {
2948
+ evaluate(name);
2949
+ }
2950
+
2951
+ for (var name in trivials) {
2952
+ var def = defs[name];
2953
+ if (def) {
2954
+ def.length = 0;
2955
+ def[0] = 'toplevel';
2956
+ def[1] = [];
2957
+ }
2958
+ delete asmData.vars[name];
2959
+ }
2960
+
2961
+ // Perform replacements TODO: save list of uses objects before, replace directly, avoid extra traverse
2962
+ traverse(func, function(node, type) {
2963
+ if (type == 'name') {
2964
+ var name = node[1];
2965
+ if (name in trivials) {
2966
+ var value = values[name];
2967
+ if (!value) throw 'missing value: ' + [func[1], name, values[name]] + ' - faulty reliance on asm zero-init?';
2968
+ return copy(value); // must copy, or else the same object can be used multiple times
2969
+ }
2970
+ }
2971
+ });
2972
+ }
2973
+
2974
+ // Prepares information for spilling of local variables
2975
+ function analyzeFunction(func, asmData) {
2976
+ var stack = []; // list of variables, each gets 8 bytes
2977
+ for (var name in asmData.params) {
2978
+ stack.push(name);
2979
+ }
2980
+ for (var name in asmData.vars) {
2981
+ stack.push(name);
2982
+ }
2983
+ asmData.stackPos = {};
2984
+ for (var i = 0; i < stack.length; i++) {
2985
+ asmData.stackPos[stack[i]] = i*8;
2986
+ }
2987
+ // Reserve an extra two spots: one for control flow var, the other for control flow data
2988
+ asmData.stackSize = (stack.length + 2)*8;
2989
+ asmData.controlStackPos = asmData.stackSize - 16;
2990
+ asmData.controlDataStackPos = asmData.stackSize - 8;
2991
+ asmData.splitCounter = 0;
2992
+ }
2993
+
2994
+ // Analyze uses - reads and writes - of variables in part of the AST of a function
2995
+ function analyzeCode(func, asmData, ast) {
2996
+ var labels = {};
2997
+ var labelCounter = 1; // 0 means no label
2998
+
2999
+ traverse(ast, function(node, type) {
3000
+ if ((type == 'label' || type in LOOP_FLOW) && node[1] && !(node[1] in labels)) {
3001
+ labels[node[1]] = labelCounter++;
3002
+ }
3003
+ });
3004
+
3005
+ var writes = {};
3006
+ var appearances = {};
3007
+ var hasReturn = false, hasBreak = false, hasContinue = false;
3008
+ var breaks = {}; // set of labels we break or continue
3009
+ var continues = {}; // to. '0' is an unlabeled one
3010
+ var breakCapturers = 0;
3011
+ var continueCapturers = 0;
3012
+
3013
+ traverse(ast, function(node, type) {
3014
+ if (type == 'assign' && node[2][0] == 'name') {
3015
+ var name = node[2][1];
3016
+ if (name in asmData.vars || name in asmData.params) {
3017
+ writes[name] = 0;
3018
+ appearances[name] = (appearances[name] || 0) - 1; // this appearance is a definition, offset the counting later
3019
+ }
3020
+ } else if (type == 'name') {
3021
+ var name = node[1];
3022
+ if (name in asmData.vars || name in asmData.params) {
3023
+ appearances[name] = (appearances[name] || 0) + 1;
3024
+ }
3025
+ } else if (type == 'return') {
3026
+ hasReturn = true;
3027
+ } else if (type == 'break') {
3028
+ var label = node[1] || 0;
3029
+ if (!label && breakCapturers > 0) return; // no label, and captured
3030
+ if (label && (label in labels)) return; // label, and defined in this code, so captured
3031
+ breaks[label || 0] = 0;
3032
+ hasBreak = true;
3033
+ } else if (type == 'continue') {
3034
+ var label = node[1] || 0;
3035
+ if (!label && continueCapturers > 0) return; // no label, and captured
3036
+ if (label && (label in labels)) return; // label, and defined in this code, so captured
3037
+ continues[label || 0] = 0;
3038
+ hasContinue = true;
3039
+ } else {
3040
+ if (type in BREAK_CAPTURERS) {
3041
+ breakCapturers++;
3042
+ }
3043
+ if (type in CONTINUE_CAPTURERS) {
3044
+ continueCapturers++;
3045
+ }
3046
+ }
3047
+ }, function(node, type) {
3048
+ if (type in BREAK_CAPTURERS) {
3049
+ breakCapturers--;
3050
+ }
3051
+ if (type in CONTINUE_CAPTURERS) {
3052
+ continueCapturers--;
3053
+ }
3054
+ });
3055
+
3056
+ var reads = {};
3057
+
3058
+ for (var name in appearances) {
3059
+ if (appearances[name] > 0) reads[name] = 0;
3060
+ }
3061
+
3062
+ return { writes: writes, reads: reads, hasReturn: hasReturn, breaks: breaks, continues: continues, labels: labels };
3063
+ }
3064
+
3065
+ function makeAssign(dst, src) {
3066
+ return ['assign', true, dst, src];
3067
+ }
3068
+ function makeStackAccess(type, pos) { // TODO: float64, not 32
3069
+ return ['sub', ['name', type == ASM_INT ? 'HEAP32' : 'HEAPF32'], ['binary', '>>', ['binary', '+', ['name', 'sp'], ['num', pos]], ['num', '2']]];
3070
+ }
3071
+ function makeIf(cond, then, else_) {
3072
+ var ret = ['if', cond, ['block', then]];
3073
+ if (else_) ret.push(['block', else_]);
3074
+ return ret;
3075
+ }
3076
+ function makeComparison(left, comp, right) {
3077
+ return ['binary', comp, left, right];
3078
+ }
3079
+
3080
+ var CONTROL_BREAK = 1, CONTROL_BREAK_LABEL = 2, CONTROL_CONTINUE = 3, CONTROL_CONTINUE_LABEL = 4, CONTROL_RETURN_VOID = 5, CONTROL_RETURN_INT = 6, CONTROL_RETURN_DOUBLE = 7;
3081
+
3082
+ var sizeToOutline = extraInfo.sizeToOutline;
3083
+ var level = 0;
3084
+
3085
+ function doOutline(func, asmData, stats, start, end) {
3086
+ printErr(' do outline ' + [func[1], level, 'range:', start, end, 'of', stats.length]);
3087
+ var code = stats.slice(start, end+1);
3088
+ var newIdent = func[1] + '$' + (asmData.splitCounter++);
3089
+ // add spills and reads before and after the call to the outlined code, and in the outlined code itself
3090
+ var codeInfo = analyzeCode(func, asmData, code);
3091
+ var reps = [];
3092
+ for (var v in codeInfo.reads) {
3093
+ if (v != 'sp') {
3094
+ reps.push(['stat', ['assign', true, ['sub', ['name', getAsmType(asmData, v) == ASM_INT ? 'HEAP32' : 'HEAPF32'], ['binary', '>>', ['binary', '+', ['name', 'sp'], ['num', asmData.stackPos[v]]], ['num', '2']]], ['name', v]]]);
3095
+ code.unshift(['stat', ['assign', true, ['name', v], ['sub', ['name', getAsmType(asmData, v) == ASM_INT ? 'HEAP32' : 'HEAPF32'], ['binary', '>>', ['binary', '+', ['name', 'sp'], ['num', asmData.stackPos[v]]], ['num', '2']]]]]);
3096
+ }
3097
+ }
3098
+ reps.push(['stat', ['call', ['name', newIdent], [['name', 'sp']]]]);
3099
+ for (var v in codeInfo.writes) {
3100
+ reps.push(['stat', ['assign', true, ['name', v], ['sub', ['name', getAsmType(asmData, v) == ASM_INT ? 'HEAP32' : 'HEAPF32'], ['binary', '>>', ['binary', '+', ['name', 'sp'], ['num', asmData.stackPos[v]]], ['num', '2']]]]]);
3101
+ code.push(['stat', ['assign', true, ['sub', ['name', getAsmType(asmData, v) == ASM_INT ? 'HEAP32' : 'HEAPF32'], ['binary', '>>', ['binary', '+', ['name', 'sp'], ['num', asmData.stackPos[v]]], ['num', '2']]], ['name', v]]]);
3102
+ }
3103
+ // Generate new function
3104
+ if (codeInfo.hasReturn || codeInfo.hasBreak || codeInfo.hasContinue) {
3105
+ // we need to capture all control flow using a top-level labeled one-time loop in the outlined function
3106
+ code = [['label', 'OL', ['do', ['num', 0], ['block', code]]]];
3107
+ var breakCapturers = 0;
3108
+ var continueCapturers = 0;
3109
+ traverse(code, function(node, type) {
3110
+ // replace all break/continue/returns with code to break out of the main one-time loop, and set the control data
3111
+ if (type == 'return') {
3112
+ var ret = ['break', 'OL'];
3113
+ if (!node[1]) {
3114
+ ret = ['seq', makeAssign(makeStackAccess(ASM_INT, asmData.controlStackPos), ['num', CONTROL_RETURN_VOID]), ret];
3115
+ } else {
3116
+ var type = detectAsmCoercion(node[1], asmData);
3117
+ ret = ['seq', makeAssign(makeStackAccess(ASM_INT, asmData.controlStackPos), ['num', type == ASM_INT ? CONTROL_RETURN_INT : CONTROL_RETURN_DOUBLE]), ret];
3118
+ ret = ['seq', makeAssign(makeStackAccess(type, asmData.controlDataStackPos), node[1]), ret];
3119
+ }
3120
+ return ret;
3121
+ } else if (type == 'break') {
3122
+ var label = node[1] || 0;
3123
+ if (label == 'OL') return; // this was just added before us, it is new replacement code
3124
+ if (!label && breakCapturers > 0) return; // no label, and captured
3125
+ if (label && (label in codeInfo.labels)) return; // label, and defined in this code, so captured
3126
+ var ret = ['break', 'OL'];
3127
+ ret = ['seq', makeAssign(makeStackAccess(ASM_INT, asmData.controlStackPos), ['num', label ? CONTROL_BREAK_LABEL : CONTROL_BREAK]), ret];
3128
+ if (label) {
3129
+ assert(label in codeInfo.labels, label + ' in ' + keys(codeInfo.labels));
3130
+ ret = ['seq', makeAssign(makeStackAccess(ASM_INT, asmData.controlDataStackPos), ['num', codeInfo.labels[label]]), ret];
3131
+ }
3132
+ return ret;
3133
+ } else if (type == 'continue') {
3134
+ var label = node[1] || 0;
3135
+ if (!label && continueCapturers > 0) return; // no label, and captured
3136
+ if (label && (label in codeInfo.labels)) return; // label, and defined in this code, so captured
3137
+ var ret = ['break', 'OL'];
3138
+ ret = ['seq', makeAssign(makeStackAccess(ASM_INT, asmData.controlStackPos), ['num', label ? CONTROL_CONTINUE_LABEL : CONTROL_CONTINUE]), ret];
3139
+ if (label) {
3140
+ ret = ['seq', makeAssign(makeStackAccess(ASM_INT, asmData.controlDataStackPos), ['num', codeInfo.labels[label]]), ret];
3141
+ }
3142
+ return ret;
3143
+ } else {
3144
+ if (type in BREAK_CAPTURERS) {
3145
+ breakCapturers++;
3146
+ }
3147
+ if (type in CONTINUE_CAPTURERS) {
3148
+ continueCapturers++;
3149
+ }
3150
+ }
3151
+ }, function(node, type) {
3152
+ if (type in BREAK_CAPTURERS) {
3153
+ breakCapturers--;
3154
+ }
3155
+ if (type in CONTINUE_CAPTURERS) {
3156
+ continueCapturers--;
3157
+ }
3158
+ });
3159
+ // read the control data at the callsite to the outlined function
3160
+ if (codeInfo.hasReturn) {
3161
+ reps.push(makeIf(
3162
+ makeComparison(makeStackAccess(ASM_INT, asmData.controlStackPos), '==', ['num', CONTROL_RETURN_VOID]),
3163
+ [['stat', ['return']]]
3164
+ ));
3165
+ reps.push(makeIf(
3166
+ makeComparison(makeStackAccess(ASM_INT, asmData.controlStackPos), '==', ['num', CONTROL_RETURN_INT]),
3167
+ [['stat', ['return', makeStackAccess(ASM_INT, asmData.controlDataStackPos)]]]
3168
+ ));
3169
+ reps.push(makeIf(
3170
+ makeComparison(makeStackAccess(ASM_INT, asmData.controlStackPos), '==', ['num', CONTROL_RETURN_DOUBLE]),
3171
+ [['stat', ['return', makeStackAccess(ASM_DOUBLE, asmData.controlDataStackPos)]]]
3172
+ ));
3173
+ }
3174
+ if (codeInfo.hasBreak) {
3175
+ reps.push(makeIf(
3176
+ makeComparison(makeStackAccess(ASM_INT, asmData.controlStackPos), '==', ['num', CONTROL_BREAK]),
3177
+ ['stat', ['break']]
3178
+ ));
3179
+ reps.push(makeIf(
3180
+ makeComparison(makeStackAccess(ASM_INT, asmData.controlStackPos), '==', ['num', CONTROL_BREAK_LABEL]),
3181
+ ['stat', ['break', makeStackAccess(ASM_INT, asmData.controlDataStackPos)]] // XXX here and below, need a switch overall possible labels
3182
+ ));
3183
+ }
3184
+ if (codeInfo.hasContinue) {
3185
+ reps.push(makeIf(
3186
+ makeComparison(makeStackAccess(ASM_INT, asmData.controlStackPos), '==', ['num', CONTROL_CONTINUE]),
3187
+ ['stat', ['break']]
3188
+ ));
3189
+ reps.push(makeIf(
3190
+ makeComparison(makeStackAccess(ASM_INT, asmData.controlStackPos), '==', ['num', CONTROL_CONTINUE_LABEL]),
3191
+ ['stat', ['continue', makeStackAccess(ASM_INT, asmData.controlDataStackPos)]] // XXX
3192
+ ));
3193
+ }
3194
+ }
3195
+ var newFunc = ['defun', newIdent, ['sp'], code];
3196
+ var newAsmData = { params: { sp: ASM_INT }, vars: {} };
3197
+ for (var v in codeInfo.reads) {
3198
+ newAsmData.vars[v] = getAsmType(asmData, v);
3199
+ }
3200
+ for (var v in codeInfo.writes) {
3201
+ newAsmData.vars[v] = getAsmType(asmData, v);
3202
+ }
3203
+ denormalizeAsm(newFunc, newAsmData);
3204
+ // replace in stats
3205
+ stats.splice.apply(stats, [start, end-start+1].concat(reps));
3206
+ return [newFunc];
3207
+ }
3208
+
3209
+ function outlineStatements(func, asmData, stats, maxSize) {
3210
+ level++;
3211
+ if (measureSize(stats) < sizeToOutline) return;
3212
+ var ret = [];
3213
+ var sizeSeen = 0;
3214
+ var end = stats.length-1;
3215
+ var i = stats.length;
3216
+ while (--i >= 0) {
3217
+ var stat = stats[i];
3218
+ var size = measureSize(stat);
3219
+ //printErr(level + ' size ' + [i, size]);
3220
+ if (size >= sizeToOutline) {
3221
+ // this by itself is big enough to inline, recurse into it and find statements to split on
3222
+ var subStatements = null;
3223
+ traverse(stat, function(node, type) {
3224
+ if (type == 'block') {
3225
+ if (measureSize(node) >= sizeToOutline) {
3226
+ var subRet = outlineStatements(func, asmData, node[1], maxSize);
3227
+ if (subRet && subRet.length > 0) ret.push.apply(ret, subRet);
3228
+ }
3229
+ return null; // do not recurse into children, outlineStatements will do so if necessary
3230
+ }
3231
+ });
3232
+ sizeSeen = 0;
3233
+ continue;
3234
+ }
3235
+ sizeSeen += size;
3236
+ // If this is big enough to outline, but no too big (if very close to the size of the full function,
3237
+ // outlining is pointless; remove stats from the end to try to achieve the good case), then outline.
3238
+ // Also, try to reduce the size if it is much larger than the hoped-for size
3239
+ while ((sizeSeen > maxSize || sizeSeen > 2*sizeToOutline) && i < end) {
3240
+ sizeSeen -= measureSize(stats[end]);
3241
+ if (sizeSeen >= sizeToOutline) {
3242
+ end--;
3243
+ } else {
3244
+ sizeSeen += measureSize(stats[end]); // abort, this took away too much
3245
+ break;
3246
+ }
3247
+ }
3248
+ if (sizeSeen >= sizeToOutline && sizeSeen <= maxSize) {
3249
+ ret.push.apply(ret, doOutline(func, asmData, stats, i, end)); // outline [i, .. ,end] inclusive
3250
+ sizeSeen = 0;
3251
+ end = i-1;
3252
+ }
3253
+ }
3254
+ level--;
3255
+ return ret;
3256
+ }
3257
+
3258
+ //
3259
+
3260
+ if (ast[0] !== 'toplevel') {
3261
+ assert(ast[0] == 'defun');
3262
+ ast = ['toplevel', [ast]];
3263
+ }
3264
+
3265
+ var funcs = ast[1];
3266
+
3267
+ var more = true;
3268
+ while (more) {
3269
+ more = false;
3270
+
3271
+ var newFuncs = [];
3272
+
3273
+ funcs.forEach(function(func) {
3274
+ var asmData = normalizeAsm(func);
3275
+ var size = measureSize(func);
3276
+ if (size >= sizeToOutline) {
3277
+ aggressiveVariableElimination(func, asmData);
3278
+ analyzeFunction(func, asmData);
3279
+ var ret = outlineStatements(func, asmData, getStatements(func), 0.5*size);
3280
+ if (ret && ret.length > 0) newFuncs.push.apply(newFuncs, ret);
3281
+ }
3282
+ denormalizeAsm(func, asmData);
3283
+ });
3284
+
3285
+ // TODO: control flow: route returns and breaks. outlined code should have all breaks/continues/returns break into the outermost scope,
3286
+ // after setting a state variable, etc.
3287
+
3288
+ if (newFuncs.length > 0) {
3289
+ // We have outlined. Add stack support: header in which we allocate enough stack space TODO
3290
+ // If sp was not present before, add it and before each return, pop the stack. also a final pop if not ending with a return TODO
3291
+ // (none of this should be done in inner functions, of course, just the original)
3292
+
3293
+ // add new functions to the toplevel, or create a toplevel if there isn't one
3294
+ ast[1].push.apply(ast[1], newFuncs);
3295
+
3296
+ funcs = newFuncs;
3297
+ more = true;
3298
+ }
3299
+ }
3300
+ }
3301
+
3302
+ // Last pass utilities
3303
+
3304
+ // Change +5 to DOT$ZERO(5). We then textually change 5 to 5.0 (uglify's ast cannot differentiate between 5 and 5.0 directly)
3305
+ function prepDotZero(ast) {
3306
+ traverse(ast, function(node, type) {
3307
+ if (type === 'unary-prefix' && node[1] === '+') {
3308
+ if (node[2][0] === 'num' ||
3309
+ (node[2][0] === 'unary-prefix' && node[2][1] === '-' && node[2][2][0] === 'num')) {
3310
+ return ['call', ['name', 'DOT$ZERO'], [node[2]]];
3311
+ }
3312
+ }
3313
+ });
3314
+ }
3315
+ function fixDotZero(js) {
3316
+ return js.replace(/DOT\$ZERO\(([-+]?(0x)?[0-9a-f]*\.?[0-9]+([eE][-+]?[0-9]+)?)\)/g, function(m, num) {
3317
+ if (num.substr(0, 2) === '0x' || num.substr(0, 3) === '-0x') {
3318
+ return eval(num) + '.0';
3319
+ }
3320
+ if (num.indexOf('.') >= 0) return num;
3321
+ var e = num.indexOf('e');
3322
+ if (e < 0) return num + '.0';
3323
+ return num.substr(0, e) + '.0' + num.substr(e);
3324
+ });
3325
+ }
3326
+
3327
+ function asmLastOpts(ast) {
3328
+ traverseGeneratedFunctions(ast, function(fun) {
3329
+ traverse(fun, function(node, type) {
3330
+ if (type === 'while' && node[1][0] === 'num' && node[1][1] === 1 && node[2][0] === 'block') {
3331
+ // This is at the end of the pipeline, we can assume all other optimizations are done, and we modify loops
3332
+ // into shapes that might confuse other passes
3333
+
3334
+ // while (1) { .. if (..) { break } } ==> do { .. } while(..)
3335
+ var stats = node[2][1];
3336
+ var last = stats[stats.length-1];
3337
+ if (last && last[0] === 'if' && !last[3] && last[2][0] === 'block' && last[2][1][0] && last[2][1][0][0] === 'break' && !last[2][1][0][1]) {
3338
+ var abort = false;
3339
+ var stack = 0;
3340
+ traverse(stats, function(node, type) {
3341
+ if (type == 'continue') {
3342
+ if (stack == 0 || node[1]) { // abort if labeled (we do not analyze labels here yet), or a continue directly on us
3343
+ abort = true;
3344
+ return true;
3345
+ }
3346
+ } else if (type in LOOP) {
3347
+ stack++;
3348
+ }
3349
+ }, function(node, type) {
3350
+ if (type in LOOP) {
3351
+ stack--;
3352
+ }
3353
+ });
3354
+ if (abort) return;
3355
+ var conditionToBreak = last[1];
3356
+ stats.pop();
3357
+ node[0] = 'do';
3358
+ node[1] = simplifyNotCompsDirect(['unary-prefix', '!', conditionToBreak]);
3359
+ return node;
3360
+ }
3361
+ } else if (type == 'binary' && node[1] == '&' && node[3][0] == 'unary-prefix' && node[3][1] == '-' && node[3][2][0] == 'num' && node[3][2][1] == 1) {
3362
+ // Change &-1 into |0, at this point the hint is no longer needed
3363
+ node[1] = '|';
3364
+ node[3] = node[3][2];
3365
+ node[3][1] = 0;
3366
+ }
3367
+ });
3368
+ });
3369
+ }
3370
+
3371
+ // Passes table
3372
+
3373
+ var minifyWhitespace = false, printMetadata = true, asm = false, last = false;
3374
+
3375
+ var passes = {
3376
+ dumpAst: dumpAst,
3377
+ dumpSrc: dumpSrc,
3378
+ unGlobalize: unGlobalize,
3379
+ removeAssignsToUndefined: removeAssignsToUndefined,
3380
+ //removeUnneededLabelSettings: removeUnneededLabelSettings,
3381
+ simplifyExpressionsPre: simplifyExpressionsPre,
3382
+ optimizeShiftsConservative: optimizeShiftsConservative,
3383
+ optimizeShiftsAggressive: optimizeShiftsAggressive,
3384
+ simplifyExpressionsPost: simplifyExpressionsPost,
3385
+ hoistMultiples: hoistMultiples,
3386
+ loopOptimizer: loopOptimizer,
3387
+ registerize: registerize,
3388
+ eliminate: eliminate,
3389
+ eliminateMemSafe: eliminateMemSafe,
3390
+ minifyGlobals: minifyGlobals,
3391
+ relocate: relocate,
3392
+ outline: outline,
3393
+ minifyWhitespace: function() { minifyWhitespace = true },
3394
+ noPrintMetadata: function() { printMetadata = false },
3395
+ asm: function() { asm = true },
3396
+ last: function() { last = true },
3397
+ };
3398
+
3399
+ // Main
3400
+
3401
+ var suffix = '';
3402
+
3403
+ arguments_ = arguments_.filter(function (arg) {
3404
+ if (!/^--/.test(arg)) return true;
3405
+
3406
+ if (arg === '--debug') debug = true;
3407
+ else throw new Error('Unrecognized flag: ' + arg);
3408
+ });
3409
+
3410
+
3411
+ var src = read(arguments_[0]);
3412
+ var ast = srcToAst(src);
3413
+ //printErr(JSON.stringify(ast)); throw 1;
3414
+ generatedFunctions = src.indexOf(GENERATED_FUNCTIONS_MARKER) >= 0;
3415
+ var extraInfoStart = src.indexOf('// EXTRA_INFO:')
3416
+ if (extraInfoStart > 0) extraInfo = JSON.parse(src.substr(extraInfoStart + 14));
3417
+ //printErr(JSON.stringify(extraInfo));
3418
+
3419
+
3420
+ arguments_.slice(1).forEach(function(arg) {
3421
+ passes[arg](ast);
3422
+ });
3423
+ if (asm && last) {
3424
+ asmLastOpts(ast); // TODO: move out of last, to make last faster when done later (as in side modules)
3425
+ prepDotZero(ast);
3426
+ }
3427
+ var js = astToSrc(ast, minifyWhitespace), old;
3428
+ if (asm && last) {
3429
+ js = fixDotZero(js);
3430
+ }
3431
+
3432
+ // remove unneeded newlines+spaces, and print
3433
+ do {
3434
+ old = js;
3435
+ js = js.replace(/\n *\n/g, '\n');
3436
+ } while (js != old);
3437
+ print(js);
3438
+ print('\n');
3439
+ print(suffix);
3440
+