webruby 0.2.7 → 0.9.1

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