webruby 0.2.2 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (245) hide show
  1. checksums.yaml +4 -4
  2. data/lib/webruby/config.rb +4 -9
  3. data/lib/webruby/rake/files.rake +2 -2
  4. data/modules/emscripten/AUTHORS +9 -1
  5. data/modules/emscripten/CONTRIBUTING.markdown +5 -0
  6. data/modules/emscripten/ChangeLog +435 -0
  7. data/modules/emscripten/cmake/Modules/FindOpenAL.cmake +26 -0
  8. data/modules/emscripten/cmake/Platform/Emscripten.cmake +9 -2
  9. data/modules/emscripten/em++ +0 -2
  10. data/modules/emscripten/emcc +92 -32
  11. data/modules/emscripten/emlink.py +16 -13
  12. data/modules/emscripten/emmake +1 -1
  13. data/modules/emscripten/emrun +918 -0
  14. data/modules/emscripten/emrun.bat +2 -0
  15. data/modules/emscripten/emscripten.py +545 -20
  16. data/modules/emscripten/src/analyzer.js +6 -1
  17. data/modules/emscripten/src/compiler.js +25 -16
  18. data/modules/emscripten/src/emrun_postjs.js +20 -0
  19. data/modules/emscripten/{tests → src}/hello_world.js +0 -0
  20. data/modules/emscripten/src/intertyper.js +45 -16
  21. data/modules/emscripten/src/jsifier.js +78 -48
  22. data/modules/emscripten/src/library.js +381 -96
  23. data/modules/emscripten/src/library_browser.js +50 -53
  24. data/modules/emscripten/src/library_egl.js +66 -24
  25. data/modules/emscripten/src/library_fs.js +122 -90
  26. data/modules/emscripten/src/library_gl.js +739 -353
  27. data/modules/emscripten/src/library_glfw.js +9 -3
  28. data/modules/emscripten/src/library_glut.js +10 -5
  29. data/modules/emscripten/src/library_idbfs.js +14 -14
  30. data/modules/emscripten/src/library_memfs.js +65 -41
  31. data/modules/emscripten/src/library_nodefs.js +61 -9
  32. data/modules/emscripten/src/library_openal.js +4 -4
  33. data/modules/emscripten/src/library_path.js +9 -13
  34. data/modules/emscripten/src/library_sdl.js +301 -64
  35. data/modules/emscripten/src/library_sockfs.js +7 -5
  36. data/modules/emscripten/src/modules.js +62 -22
  37. data/modules/emscripten/src/parseTools.js +135 -102
  38. data/modules/emscripten/src/postamble.js +3 -4
  39. data/modules/emscripten/src/preamble.js +49 -29
  40. data/modules/emscripten/src/proxyClient.js +1 -1
  41. data/modules/emscripten/src/proxyWorker.js +10 -10
  42. data/modules/emscripten/src/relooper/Relooper.cpp +15 -4
  43. data/modules/emscripten/src/runtime.js +32 -8
  44. data/modules/emscripten/src/settings.js +25 -8
  45. data/modules/emscripten/src/shell.html +6 -3
  46. data/modules/emscripten/src/shell.js +13 -11
  47. data/modules/emscripten/src/simd.js +602 -432
  48. data/modules/emscripten/src/struct_info.json +22 -2
  49. data/modules/emscripten/src/utility.js +32 -17
  50. data/modules/emscripten/system/include/SDL/SDL_events.h +1 -0
  51. data/modules/emscripten/system/include/compat/ctype.h +17 -0
  52. data/modules/emscripten/system/include/compat/wchar.h +23 -0
  53. data/modules/emscripten/system/include/compat/wctype.h +23 -0
  54. data/modules/emscripten/system/include/emscripten/emmintrin.h +87 -0
  55. data/modules/emscripten/system/include/emscripten/emscripten.h +30 -4
  56. data/modules/emscripten/system/include/emscripten/vector.h +29 -1
  57. data/modules/emscripten/system/include/emscripten/xmmintrin.h +131 -0
  58. data/modules/emscripten/system/include/libcxx/CREDITS.TXT +9 -1
  59. data/modules/emscripten/system/include/libcxx/__bit_reference +8 -8
  60. data/modules/emscripten/system/include/libcxx/__config +95 -17
  61. data/modules/emscripten/system/include/libcxx/__debug +25 -4
  62. data/modules/emscripten/system/include/libcxx/__functional_03 +7 -7
  63. data/modules/emscripten/system/include/libcxx/__functional_base +169 -9
  64. data/modules/emscripten/system/include/libcxx/__functional_base_03 +1 -1
  65. data/modules/emscripten/system/include/libcxx/__hash_table +25 -25
  66. data/modules/emscripten/system/include/libcxx/__locale +21 -19
  67. data/modules/emscripten/system/include/libcxx/__mutex_base +2 -33
  68. data/modules/emscripten/system/include/libcxx/__split_buffer +9 -9
  69. data/modules/emscripten/system/include/libcxx/__std_stream +14 -0
  70. data/modules/emscripten/system/include/libcxx/__tree +35 -26
  71. data/modules/emscripten/system/include/libcxx/__tuple +15 -15
  72. data/modules/emscripten/system/include/libcxx/__tuple_03 +2 -2
  73. data/modules/emscripten/system/include/libcxx/__undef_min_max +8 -0
  74. data/modules/emscripten/system/include/libcxx/algorithm +121 -110
  75. data/modules/emscripten/system/include/libcxx/array +15 -15
  76. data/modules/emscripten/system/include/libcxx/bitset +4 -4
  77. data/modules/emscripten/system/include/libcxx/chrono +51 -17
  78. data/modules/emscripten/system/include/libcxx/cmath +25 -23
  79. data/modules/emscripten/system/include/libcxx/codecvt +21 -18
  80. data/modules/emscripten/system/include/libcxx/complex +48 -7
  81. data/modules/emscripten/system/include/libcxx/cstddef +1 -1
  82. data/modules/emscripten/system/include/libcxx/cstdio +8 -1
  83. data/modules/emscripten/system/include/libcxx/cstdlib +1 -1
  84. data/modules/emscripten/system/include/libcxx/cwchar +1 -1
  85. data/modules/emscripten/system/include/libcxx/deque +26 -12
  86. data/modules/emscripten/system/include/libcxx/dynarray +311 -0
  87. data/modules/emscripten/system/include/libcxx/exception +4 -4
  88. data/modules/emscripten/system/include/libcxx/ext/__hash +3 -3
  89. data/modules/emscripten/system/include/libcxx/ext/hash_map +19 -15
  90. data/modules/emscripten/system/include/libcxx/ext/hash_set +7 -3
  91. data/modules/emscripten/system/include/libcxx/forward_list +33 -7
  92. data/modules/emscripten/system/include/libcxx/fstream +4 -4
  93. data/modules/emscripten/system/include/libcxx/functional +200 -170
  94. data/modules/emscripten/system/include/libcxx/future +83 -39
  95. data/modules/emscripten/system/include/libcxx/initializer_list +24 -11
  96. data/modules/emscripten/system/include/libcxx/iomanip +147 -0
  97. data/modules/emscripten/system/include/libcxx/ios +24 -16
  98. data/modules/emscripten/system/include/libcxx/iosfwd +19 -19
  99. data/modules/emscripten/system/include/libcxx/istream +13 -8
  100. data/modules/emscripten/system/include/libcxx/iterator +108 -417
  101. data/modules/emscripten/system/include/libcxx/limits +8 -4
  102. data/modules/emscripten/system/include/libcxx/list +28 -8
  103. data/modules/emscripten/system/include/libcxx/locale +153 -390
  104. data/modules/emscripten/system/include/libcxx/map +280 -100
  105. data/modules/emscripten/system/include/libcxx/memory +49 -97
  106. data/modules/emscripten/system/include/libcxx/mutex +2 -2
  107. data/modules/emscripten/system/include/libcxx/new +43 -14
  108. data/modules/emscripten/system/include/libcxx/numeric +2 -2
  109. data/modules/emscripten/system/include/libcxx/optional +697 -0
  110. data/modules/emscripten/system/include/libcxx/ostream +17 -8
  111. data/modules/emscripten/system/include/libcxx/queue +5 -5
  112. data/modules/emscripten/system/include/libcxx/random +53 -51
  113. data/modules/emscripten/system/include/libcxx/ratio +11 -11
  114. data/modules/emscripten/system/include/libcxx/readme.txt +1 -1
  115. data/modules/emscripten/system/include/libcxx/regex +23 -20
  116. data/modules/emscripten/system/include/libcxx/scoped_allocator +1 -1
  117. data/modules/emscripten/system/include/libcxx/set +166 -2
  118. data/modules/emscripten/system/include/libcxx/shared_mutex +419 -0
  119. data/modules/emscripten/system/include/libcxx/sstream +4 -4
  120. data/modules/emscripten/system/include/libcxx/stack +3 -3
  121. data/modules/emscripten/system/include/libcxx/streambuf +5 -5
  122. data/modules/emscripten/system/include/libcxx/string +372 -324
  123. data/modules/emscripten/system/include/libcxx/support/ibm/limits.h +99 -0
  124. data/modules/emscripten/system/include/libcxx/support/ibm/support.h +54 -0
  125. data/modules/emscripten/system/include/libcxx/support/ibm/xlocale.h +326 -0
  126. data/modules/emscripten/system/include/libcxx/support/win32/limits_win32.h +6 -6
  127. data/modules/emscripten/system/include/libcxx/support/win32/locale_win32.h +15 -15
  128. data/modules/emscripten/system/include/libcxx/support/win32/math_win32.h +2 -0
  129. data/modules/emscripten/system/include/libcxx/support/win32/support.h +6 -1
  130. data/modules/emscripten/system/include/libcxx/system_error +14 -8
  131. data/modules/emscripten/system/include/libcxx/thread +7 -8
  132. data/modules/emscripten/system/include/libcxx/tuple +29 -88
  133. data/modules/emscripten/system/include/libcxx/type_traits +253 -209
  134. data/modules/emscripten/system/include/libcxx/typeindex +3 -3
  135. data/modules/emscripten/system/include/libcxx/unordered_map +162 -101
  136. data/modules/emscripten/system/include/libcxx/unordered_set +79 -2
  137. data/modules/emscripten/system/include/libcxx/utility +20 -20
  138. data/modules/emscripten/system/include/libcxx/valarray +23 -23
  139. data/modules/emscripten/system/include/libcxx/vector +114 -91
  140. data/modules/emscripten/system/lib/libc/musl/src/regex/regcomp.c +3352 -0
  141. data/modules/emscripten/system/lib/libc/musl/src/regex/regerror.c +35 -0
  142. data/modules/emscripten/system/lib/libc/musl/src/regex/regexec.c +1011 -0
  143. data/modules/emscripten/system/lib/libc/musl/src/regex/tre-mem.c +158 -0
  144. data/modules/emscripten/system/lib/libc/musl/src/regex/tre.h +231 -0
  145. data/modules/emscripten/system/lib/libcextra.symbols +7 -0
  146. data/modules/emscripten/system/lib/libcxx/CREDITS.TXT +9 -1
  147. data/modules/emscripten/system/lib/libcxx/algorithm.cpp +1 -0
  148. data/modules/emscripten/system/lib/libcxx/debug.cpp +66 -42
  149. data/modules/emscripten/system/lib/libcxx/exception.cpp +88 -16
  150. data/modules/emscripten/system/lib/libcxx/future.cpp +6 -0
  151. data/modules/emscripten/system/lib/libcxx/ios.cpp +7 -2
  152. data/modules/emscripten/system/lib/libcxx/iostream.cpp +8 -8
  153. data/modules/emscripten/system/lib/libcxx/locale.cpp +38 -11
  154. data/modules/emscripten/system/lib/libcxx/mutex.cpp +3 -0
  155. data/modules/emscripten/system/lib/libcxx/new.cpp +44 -10
  156. data/modules/emscripten/system/lib/libcxx/optional.cpp +25 -0
  157. data/modules/emscripten/system/lib/libcxx/random.cpp +26 -0
  158. data/modules/emscripten/system/lib/libcxx/readme.txt +1 -1
  159. data/modules/emscripten/system/lib/libcxx/shared_mutex.cpp +101 -0
  160. data/modules/emscripten/system/lib/libcxx/stdexcept.cpp +11 -7
  161. data/modules/emscripten/system/lib/libcxx/string.cpp +3 -1
  162. data/modules/emscripten/system/lib/libcxx/strstream.cpp +7 -7
  163. data/modules/emscripten/system/lib/libcxx/support/win32/locale_win32.cpp +12 -13
  164. data/modules/emscripten/system/lib/libcxx/support/win32/support.cpp +33 -36
  165. data/modules/emscripten/system/lib/libcxx/symbols +187 -168
  166. data/modules/emscripten/system/lib/libcxx/system_error.cpp +1 -0
  167. data/modules/emscripten/system/lib/libcxx/thread.cpp +7 -3
  168. data/modules/emscripten/system/lib/libcxx/typeinfo.cpp +9 -6
  169. data/modules/emscripten/system/lib/libcxx/valarray.cpp +2 -0
  170. data/modules/emscripten/third_party/lzma.js/doit.bat +4 -0
  171. data/modules/emscripten/third_party/lzma.js/doit.sh +9 -2
  172. data/modules/emscripten/tools/cache.py +5 -7
  173. data/modules/emscripten/tools/cache.pyc +0 -0
  174. data/modules/emscripten/tools/eliminator/asm-eliminator-test-output.js +7 -0
  175. data/modules/emscripten/tools/eliminator/asm-eliminator-test.js +9 -1
  176. data/modules/emscripten/tools/eliminator/eliminator-test-output.js +3 -0
  177. data/modules/emscripten/tools/eliminator/eliminator-test.js +9 -1
  178. data/modules/emscripten/tools/file_packager.py +93 -50
  179. data/modules/emscripten/tools/js-optimizer.js +98 -48
  180. data/modules/emscripten/tools/js_optimizer.py +4 -4
  181. data/modules/emscripten/tools/js_optimizer.pyc +0 -0
  182. data/modules/emscripten/tools/jsrun.py +1 -1
  183. data/modules/emscripten/tools/jsrun.pyc +0 -0
  184. data/modules/emscripten/tools/response_file.py +6 -0
  185. data/modules/emscripten/tools/response_file.pyc +0 -0
  186. data/modules/emscripten/tools/settings_template_readonly.py +2 -0
  187. data/modules/emscripten/tools/shared.py +88 -34
  188. data/modules/emscripten/tools/shared.pyc +0 -0
  189. data/modules/emscripten/tools/split.py +21 -13
  190. data/modules/mruby/build_config.rb +7 -1
  191. data/modules/mruby/doc/compile/README.md +5 -9
  192. data/modules/mruby/include/mrbconf.h +5 -2
  193. data/modules/mruby/include/mruby/array.h +1 -0
  194. data/modules/mruby/include/mruby/compile.h +2 -4
  195. data/modules/mruby/include/mruby/dump.h +7 -16
  196. data/modules/mruby/include/mruby/hash.h +1 -1
  197. data/modules/mruby/include/mruby/irep.h +14 -2
  198. data/modules/mruby/include/mruby/khash.h +8 -7
  199. data/modules/mruby/include/mruby/string.h +1 -0
  200. data/modules/mruby/include/mruby/value.h +5 -2
  201. data/modules/mruby/include/mruby.h +12 -13
  202. data/modules/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +16 -6
  203. data/modules/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +18 -30
  204. data/modules/mruby/mrbgems/mruby-fiber/src/fiber.c +21 -0
  205. data/modules/mruby/mrbgems/mruby-math/src/math.c +1 -1
  206. data/modules/mruby/mrbgems/mruby-random/src/random.c +144 -47
  207. data/modules/mruby/mrbgems/mruby-random/test/random.rb +44 -0
  208. data/modules/mruby/mrbgems/mruby-struct/src/struct.c +5 -5
  209. data/modules/mruby/mrblib/numeric.rb +99 -33
  210. data/modules/mruby/src/array.c +11 -4
  211. data/modules/mruby/src/backtrace.c +2 -2
  212. data/modules/mruby/src/class.c +49 -30
  213. data/modules/mruby/src/codegen.c +131 -79
  214. data/modules/mruby/src/debug.c +1 -1
  215. data/modules/mruby/src/dump.c +213 -163
  216. data/modules/mruby/src/error.c +17 -17
  217. data/modules/mruby/src/error.h +1 -1
  218. data/modules/mruby/src/etc.c +10 -0
  219. data/modules/mruby/src/gc.c +35 -17
  220. data/modules/mruby/src/hash.c +5 -5
  221. data/modules/mruby/src/kernel.c +36 -14
  222. data/modules/mruby/src/load.c +238 -296
  223. data/modules/mruby/src/numeric.c +18 -98
  224. data/modules/mruby/src/object.c +3 -5
  225. data/modules/mruby/src/parse.y +63 -56
  226. data/modules/mruby/src/proc.c +8 -5
  227. data/modules/mruby/src/re.h +0 -1
  228. data/modules/mruby/src/state.c +65 -27
  229. data/modules/mruby/src/string.c +3 -31
  230. data/modules/mruby/src/symbol.c +3 -3
  231. data/modules/mruby/src/variable.c +12 -5
  232. data/modules/mruby/src/vm.c +90 -72
  233. data/modules/mruby/tasks/mruby_build.rake +10 -1
  234. data/modules/mruby/tasks/toolchains/gcc.rake +12 -2
  235. data/modules/mruby/tasks/toolchains/{vs2012.rake → visualcpp.rake} +1 -1
  236. data/modules/mruby/test/driver.c +3 -3
  237. data/modules/mruby/test/t/array.rb +5 -5
  238. data/modules/mruby/test/t/class.rb +14 -1
  239. data/modules/mruby/test/t/kernel.rb +4 -0
  240. data/modules/mruby/test/t/module.rb +4 -4
  241. data/modules/mruby/test/t/nameerror.rb +1 -1
  242. data/modules/mruby/tools/mrbc/mrbc.c +23 -17
  243. data/modules/mruby/travis_config.rb +10 -1
  244. metadata +28 -5
  245. data/modules/mruby/tasks/toolchains/vs2010.rake +0 -3
@@ -618,6 +618,7 @@ function simplifyExpressions(ast) {
618
618
 
619
619
  if (asm) {
620
620
  if (hasTempDoublePtr) {
621
+ var asmData = normalizeAsm(ast);
621
622
  traverse(ast, function(node, type) {
622
623
  if (type === 'assign') {
623
624
  if (node[1] === true && node[2][0] === 'sub' && node[2][1][0] === 'name' && node[2][1][1] === 'HEAP32') {
@@ -642,7 +643,7 @@ function simplifyExpressions(ast) {
642
643
  node[2][0] !== 'seq') { // avoid (x, y, z) which can be used for tempDoublePtr on doubles for alignment fixes
643
644
  if (node[1][2][1][1] === 'HEAP32') {
644
645
  node[1][3][1][1] = 'HEAPF32';
645
- return ['unary-prefix', '+', node[1][3]];
646
+ return makeAsmCoercion(node[1][3], detectAsmCoercion(node[2]));
646
647
  } else {
647
648
  node[1][3][1][1] = 'HEAP32';
648
649
  return ['binary', '|', node[1][3], ['num', 0]];
@@ -686,7 +687,6 @@ function simplifyExpressions(ast) {
686
687
  }
687
688
  }
688
689
  });
689
- var asmData = normalizeAsm(ast);
690
690
  for (var v in bitcastVars) {
691
691
  var info = bitcastVars[v];
692
692
  // good variables define only one type, use only one type, have definitions and uses, and define as a different type than they use
@@ -1142,13 +1142,28 @@ function simplifyNotComps(ast) {
1142
1142
  simplifyNotCompsPass = false;
1143
1143
  }
1144
1144
 
1145
- var NO_SIDE_EFFECTS = set('num', 'name');
1145
+ function callHasSideEffects(node) { // checks if the call itself (not the args) has side effects (or is not statically known)
1146
+ return !(node[1][0] === 'name' && /^Math_/.test(node[1][1]));
1147
+ }
1146
1148
 
1147
1149
  function hasSideEffects(node) { // this is 99% incomplete!
1148
- if (node[0] in NO_SIDE_EFFECTS) return false;
1149
- if (node[0] === 'unary-prefix') return hasSideEffects(node[2]);
1150
- if (node[0] === 'binary') return hasSideEffects(node[2]) || hasSideEffects(node[3]);
1151
- return true;
1150
+ switch (node[0]) {
1151
+ case 'num': case 'name': case 'string': return false;
1152
+ case 'unary-prefix': return hasSideEffects(node[2]);
1153
+ case 'binary': return hasSideEffects(node[2]) || hasSideEffects(node[3]);
1154
+ case 'sub': return hasSideEffects(node[1]) || hasSideEffects(node[2]);
1155
+ case 'call': {
1156
+ if (callHasSideEffects(node)) return true;
1157
+ // This is a statically known call, with no side effects. only args can side effect us
1158
+ var args = node[2];
1159
+ var num = args.length;
1160
+ for (var i = 0; i < num; i++) {
1161
+ if (hasSideEffects(args[i])) return true;
1162
+ }
1163
+ return false;
1164
+ }
1165
+ default: return true;
1166
+ }
1152
1167
  }
1153
1168
 
1154
1169
  // Clear out empty ifs and blocks, and redundant blocks/stats and so forth
@@ -1515,21 +1530,33 @@ function unVarify(vars, ret) { // transform var x=1, y=2 etc. into (x=1, y=2), i
1515
1530
  // annotations, plus explicit metadata) and denormalize (vice versa)
1516
1531
  var ASM_INT = 0;
1517
1532
  var ASM_DOUBLE = 1;
1533
+ var ASM_FLOAT = 2;
1518
1534
 
1519
1535
  function detectAsmCoercion(node, asmInfo) {
1520
1536
  // for params, +x vs x|0, for vars, 0.0 vs 0
1521
1537
  if (node[0] === 'num' && node[1].toString().indexOf('.') >= 0) return ASM_DOUBLE;
1522
1538
  if (node[0] === 'unary-prefix') return ASM_DOUBLE;
1539
+ if (node[0] === 'call' && node[1][0] === 'name' && node[1][1] === 'Math_fround') return ASM_FLOAT;
1523
1540
  if (asmInfo && node[0] == 'name') return getAsmType(node[1], asmInfo);
1524
1541
  return ASM_INT;
1525
1542
  }
1526
1543
 
1527
1544
  function makeAsmCoercion(node, type) {
1528
- return type === ASM_INT ? ['binary', '|', node, ['num', 0]] : ['unary-prefix', '+', node];
1545
+ switch (type) {
1546
+ case ASM_INT: return ['binary', '|', node, ['num', 0]];
1547
+ case ASM_DOUBLE: return ['unary-prefix', '+', node];
1548
+ case ASM_FLOAT: return ['call', ['name', 'Math_fround'], [node]];
1549
+ default: throw 'wha? ' + JSON.stringify([node, type]) + new Error().stack;
1550
+ }
1529
1551
  }
1530
1552
 
1531
1553
  function makeAsmVarDef(v, type) {
1532
- return [v, type === ASM_INT ? ['num', 0] : ['unary-prefix', '+', ['num', 0]]];
1554
+ switch (type) {
1555
+ case ASM_INT: return [v, ['num', 0]];
1556
+ case ASM_DOUBLE: return [v, ['unary-prefix', '+', ['num', 0]]];
1557
+ case ASM_FLOAT: return [v, ['call', ['name', 'Math_fround'], [['num', 0]]]];
1558
+ default: throw 'wha?';
1559
+ }
1533
1560
  }
1534
1561
 
1535
1562
  function getAsmType(name, asmInfo) {
@@ -1568,7 +1595,8 @@ function normalizeAsm(func) {
1568
1595
  var name = v[0];
1569
1596
  var value = v[1];
1570
1597
  if (!(name in data.vars)) {
1571
- assert(value[0] === 'num' || (value[0] === 'unary-prefix' && value[2][0] === 'num')); // must be valid coercion no-op
1598
+ assert(value[0] === 'num' || (value[0] === 'unary-prefix' && value[2][0] === 'num') // must be valid coercion no-op
1599
+ || (value[0] === 'call' && value[1][0] === 'name' && value[1][1] === 'Math_fround'));
1572
1600
  data.vars[name] = detectAsmCoercion(value);
1573
1601
  v.length = 1; // make an un-assigning var
1574
1602
  } else {
@@ -1917,7 +1945,7 @@ function registerize(ast) {
1917
1945
  // we just use a fresh register to make sure we avoid this, but it could be
1918
1946
  // optimized to check for safe registers (free, and not used in this loop level).
1919
1947
  var varRegs = {}; // maps variables to the register they will use all their life
1920
- var freeRegsClasses = asm ? [[], []] : []; // two classes for asm, one otherwise
1948
+ var freeRegsClasses = asm ? [[], [], []] : []; // two classes for asm, one otherwise XXX - hardcoded length
1921
1949
  var nextReg = 1;
1922
1950
  var fullNames = {};
1923
1951
  var loopRegs = {}; // for each loop nesting level, the list of bound variables
@@ -2031,6 +2059,33 @@ function registerize(ast) {
2031
2059
  }
2032
2060
  }
2033
2061
  denormalizeAsm(fun, finalAsmData);
2062
+ if (extraInfo && extraInfo.globals) {
2063
+ // minify in asm var definitions, that denormalizeAsm just generated
2064
+ function minify(value) {
2065
+ if (value && value[0] === 'call' && value[1][0] === 'name') {
2066
+ var name = value[1][1];
2067
+ var minified = extraInfo.globals[name];
2068
+ if (minified) {
2069
+ value[1][1] = minified;
2070
+ }
2071
+ }
2072
+ }
2073
+ var stats = fun[3];
2074
+ for (var i = 0; i < stats.length; i++) {
2075
+ var line = stats[i];
2076
+ if (i >= fun[2].length && line[0] !== 'var') break; // when we pass the arg and var coercions, break
2077
+ if (line[0] === 'stat') {
2078
+ assert(line[1][0] === 'assign');
2079
+ minify(line[1][3]);
2080
+ } else {
2081
+ assert(line[0] === 'var');
2082
+ var pairs = line[1];
2083
+ for (var j = 0; j < pairs.length; j++) {
2084
+ minify(pairs[j][1]);
2085
+ }
2086
+ }
2087
+ }
2088
+ }
2034
2089
  }
2035
2090
  });
2036
2091
  }
@@ -2068,7 +2123,6 @@ function registerize(ast) {
2068
2123
  // can happen in ALLOW_MEMORY_GROWTH mode
2069
2124
 
2070
2125
  var ELIMINATION_SAFE_NODES = set('var', 'assign', 'call', 'if', 'toplevel', 'do', 'return', 'label', 'switch'); // do is checked carefully, however
2071
- var NODES_WITHOUT_ELIMINATION_SIDE_EFFECTS = set('name', 'num', 'string', 'binary', 'sub', 'unary-prefix');
2072
2126
  var IGNORABLE_ELIMINATOR_SCAN_NODES = set('num', 'toplevel', 'string', 'break', 'continue', 'dot'); // dot can only be STRING_TABLE.*
2073
2127
  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)
2074
2128
 
@@ -2160,7 +2214,7 @@ function eliminate(ast, memSafe) {
2160
2214
  if (definitions[name] === 1 && uses[name] === 1) {
2161
2215
  potentials[name] = 1;
2162
2216
  } 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)
2163
- var hasSideEffects = false;
2217
+ var sideEffects = false;
2164
2218
  var value = values[name];
2165
2219
  if (value) {
2166
2220
  // TODO: merge with other side effect code
@@ -2170,15 +2224,10 @@ function eliminate(ast, memSafe) {
2170
2224
  if (!(value[0] === 'seq' && value[1][0] === 'assign' && value[1][2][0] === 'sub' && value[1][2][2][0] === 'binary' && value[1][2][2][1] === '>>' &&
2171
2225
  value[1][2][2][2][0] === 'name' && value[1][2][2][2][1] === 'tempDoublePtr')) {
2172
2226
  // If not that, then traverse and scan normally.
2173
- traverse(value, function(node, type) {
2174
- if (!(type in NODES_WITHOUT_ELIMINATION_SIDE_EFFECTS)) {
2175
- hasSideEffects = true; // cannot remove this unused variable, constructing it has side effects
2176
- return true;
2177
- }
2178
- });
2227
+ sideEffects = hasSideEffects(value);
2179
2228
  }
2180
2229
  }
2181
- if (!hasSideEffects) {
2230
+ if (!sideEffects) {
2182
2231
  varsToRemove[name] = !definitions[name] ? 2 : 1; // remove it normally
2183
2232
  sideEffectFree[name] = true;
2184
2233
  // Each time we remove a variable with 0 uses, if its value has no
@@ -2437,14 +2486,16 @@ function eliminate(ast, memSafe) {
2437
2486
  for (var i = 0; i < args.length; i++) {
2438
2487
  traverseInOrder(args[i]);
2439
2488
  }
2440
- // these two invalidations will also invalidate calls
2441
- if (!globalsInvalidated) {
2442
- invalidateGlobals();
2443
- globalsInvalidated = true;
2444
- }
2445
- if (!memoryInvalidated) {
2446
- invalidateMemory();
2447
- memoryInvalidated = true;
2489
+ if (callHasSideEffects(node)) {
2490
+ // these two invalidations will also invalidate calls
2491
+ if (!globalsInvalidated) {
2492
+ invalidateGlobals();
2493
+ globalsInvalidated = true;
2494
+ }
2495
+ if (!memoryInvalidated) {
2496
+ invalidateMemory();
2497
+ memoryInvalidated = true;
2498
+ }
2448
2499
  }
2449
2500
  } else if (type === 'if') {
2450
2501
  if (allowTracking) {
@@ -2485,6 +2536,10 @@ function eliminate(ast, memSafe) {
2485
2536
  } else if (type === 'return') {
2486
2537
  if (node[1]) traverseInOrder(node[1]);
2487
2538
  } else if (type === 'conditional') {
2539
+ if (!callsInvalidated) { // invalidate calls, since we cannot eliminate them into a branch of an LLVM select/JS conditional that does not execute
2540
+ invalidateCalls();
2541
+ callsInvalidated = true;
2542
+ }
2488
2543
  traverseInOrder(node[1]);
2489
2544
  traverseInOrder(node[2]);
2490
2545
  traverseInOrder(node[3]);
@@ -3169,7 +3224,7 @@ function outline(ast) {
3169
3224
 
3170
3225
  var writes = {};
3171
3226
  var namings = {};
3172
- var hasReturn = false, hasReturnInt = false, hasReturnDouble = false, hasBreak = false, hasContinue = false;
3227
+ var hasReturn = false, hasReturnType = {}, hasBreak = false, hasContinue = false;
3173
3228
  var breaks = {}; // set of labels we break or continue
3174
3229
  var continues = {}; // to (name -> id, just like labels)
3175
3230
  var breakCapturers = 0;
@@ -3189,10 +3244,8 @@ function outline(ast) {
3189
3244
  } else if (type == 'return') {
3190
3245
  if (!node[1]) {
3191
3246
  hasReturn = true;
3192
- } else if (detectAsmCoercion(node[1]) == ASM_INT) {
3193
- hasReturnInt = true;
3194
3247
  } else {
3195
- hasReturnDouble = true;
3248
+ hasReturnType[detectAsmCoercion(node[1])] = true;
3196
3249
  }
3197
3250
  } else if (type == 'break') {
3198
3251
  var label = node[1] || 0;
@@ -3222,7 +3275,6 @@ function outline(ast) {
3222
3275
  continueCapturers--;
3223
3276
  }
3224
3277
  });
3225
- assert(hasReturn + hasReturnInt + hasReturnDouble <= 1);
3226
3278
 
3227
3279
  var reads = {};
3228
3280
  for (var v in namings) {
@@ -3230,7 +3282,7 @@ function outline(ast) {
3230
3282
  if (actualReads > 0) reads[v] = actualReads;
3231
3283
  }
3232
3284
 
3233
- return { writes: writes, reads: reads, hasReturn: hasReturn, hasReturnInt: hasReturnInt, hasReturnDouble: hasReturnDouble, hasBreak: hasBreak, hasContinue: hasContinue, breaks: breaks, continues: continues, labels: labels };
3285
+ return { writes: writes, reads: reads, hasReturn: hasReturn, hasReturnType: hasReturnType, hasBreak: hasBreak, hasContinue: hasContinue, breaks: breaks, continues: continues, labels: labels };
3234
3286
  }
3235
3287
 
3236
3288
  function makeAssign(dst, src) {
@@ -3251,7 +3303,10 @@ function outline(ast) {
3251
3303
  return ['switch', value, cases];
3252
3304
  }
3253
3305
 
3254
- 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;
3306
+ 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;
3307
+ function controlFromAsmType(asmType) {
3308
+ return CONTROL_RETURN_INT + (asmType | 0); // assumes ASM_INT starts at 0, and order of these two is identical!
3309
+ }
3255
3310
 
3256
3311
  var sizeToOutline = null; // customized per function and as we make progress
3257
3312
  function calculateThreshold(func, asmData) {
@@ -3310,7 +3365,7 @@ function outline(ast) {
3310
3365
  });
3311
3366
 
3312
3367
  // Generate new function
3313
- if (codeInfo.hasReturn || codeInfo.hasReturnInt || codeInfo.hasReturnDouble || codeInfo.hasBreak || codeInfo.hasContinue) {
3368
+ if (codeInfo.hasReturn || codeInfo.hasReturnType[ASM_INT] || codeInfo.hasReturnType[ASM_DOUBLE] || codeInfo.hasReturnType[ASM_FLOAT] || codeInfo.hasBreak || codeInfo.hasContinue) {
3314
3369
  // we need to capture all control flow using a top-level labeled one-time loop in the outlined function
3315
3370
  var breakCapturers = 0;
3316
3371
  var continueCapturers = 0;
@@ -3335,7 +3390,7 @@ function outline(ast) {
3335
3390
  ret.push(['stat', makeAssign(makeStackAccess(ASM_INT, asmData.controlStackPos(outlineIndex)), ['num', CONTROL_RETURN_VOID])]);
3336
3391
  } else {
3337
3392
  var type = detectAsmCoercion(node[1], asmData);
3338
- ret.push(['stat', makeAssign(makeStackAccess(ASM_INT, asmData.controlStackPos(outlineIndex)), ['num', type == ASM_INT ? CONTROL_RETURN_INT : CONTROL_RETURN_DOUBLE])]);
3393
+ ret.push(['stat', makeAssign(makeStackAccess(ASM_INT, asmData.controlStackPos(outlineIndex)), ['num', controlFromAsmType(type)])]);
3339
3394
  ret.push(['stat', makeAssign(makeStackAccess(type, asmData.controlDataStackPos(outlineIndex)), node[1])]);
3340
3395
  }
3341
3396
  ret.push(['stat', ['break', 'OL']]);
@@ -3398,16 +3453,10 @@ function outline(ast) {
3398
3453
  [['stat', ['return']]]
3399
3454
  ));
3400
3455
  }
3401
- if (codeInfo.hasReturnInt) {
3456
+ for (var returnType in codeInfo.hasReturnType) {
3402
3457
  reps.push(makeIf(
3403
- makeComparison(makeAsmCoercion(['name', 'tempValue'], ASM_INT), '==', ['num', CONTROL_RETURN_INT]),
3404
- [['stat', ['return', makeAsmCoercion(['name', 'tempInt'], ASM_INT)]]]
3405
- ));
3406
- }
3407
- if (codeInfo.hasReturnDouble) {
3408
- reps.push(makeIf(
3409
- makeComparison(makeAsmCoercion(['name', 'tempValue'], ASM_INT), '==', ['num', CONTROL_RETURN_DOUBLE]),
3410
- [['stat', ['return', makeAsmCoercion(['name', 'tempDouble'], ASM_DOUBLE)]]]
3458
+ makeComparison(makeAsmCoercion(['name', 'tempValue'], ASM_INT), '==', ['num', controlFromAsmType(returnType)]),
3459
+ [['stat', ['return', makeAsmCoercion(['name', 'tempInt'], returnType | 0)]]]
3411
3460
  ));
3412
3461
  }
3413
3462
  if (codeInfo.hasBreak) {
@@ -3486,8 +3535,9 @@ function outline(ast) {
3486
3535
  var last = getStatements(func)[getStatements(func).length-1];
3487
3536
  if (last[0] === 'stat') last = last[1];
3488
3537
  if (last[0] !== 'return') {
3489
- if (allCodeInfo.hasReturnInt || allCodeInfo.hasReturnDouble) {
3490
- getStatements(func).push(['stat', ['return', makeAsmCoercion(['num', 0], allCodeInfo.hasReturnInt ? ASM_INT : ASM_DOUBLE)]]);
3538
+ for (var returnType in codeInfo.hasReturnType) {
3539
+ getStatements(func).push(['stat', ['return', makeAsmCoercion(['num', 0], returnType | 0)]]);
3540
+ break;
3491
3541
  }
3492
3542
  }
3493
3543
  outliningParents[newIdent] = func[1];
@@ -29,13 +29,13 @@ class Minifier:
29
29
  during registerize perform minification of locals.
30
30
  '''
31
31
 
32
- def __init__(self, js, js_engine):
32
+ def __init__(self, js, js_engine, MAX_NAMES):
33
33
  self.js = js
34
34
  self.js_engine = js_engine
35
+ MAX_NAMES = min(MAX_NAMES, 120000)
35
36
 
36
37
  # Create list of valid short names
37
38
 
38
- MAX_NAMES = 80000
39
39
  INVALID_2 = set(['do', 'if', 'in'])
40
40
  INVALID_3 = set(['for', 'new', 'try', 'var', 'env', 'let'])
41
41
 
@@ -56,7 +56,6 @@ class Minifier:
56
56
  if len(self.names) >= MAX_NAMES: break
57
57
  curr = a + b + c
58
58
  if curr not in INVALID_3: self.names.append(curr)
59
- #print >> sys.stderr, self.names
60
59
 
61
60
  def minify_shell(self, shell, minify_whitespace, source_map=False):
62
61
  #print >> sys.stderr, "MINIFY SHELL 1111111111", shell, "\n222222222222222"
@@ -187,7 +186,8 @@ EMSCRIPTEN_FUNCS();
187
186
  ''' + js[end_funcs + len(end_funcs_marker):end_asm + len(end_asm_marker)]
188
187
  js = js[start_funcs + len(start_funcs_marker):end_funcs]
189
188
 
190
- minifier = Minifier(js, js_engine)
189
+ # we assume there is a maximum of one new name per line
190
+ minifier = Minifier(js, js_engine, js.count('\n') + asm_shell.count('\n'))
191
191
  asm_shell_pre, asm_shell_post = minifier.minify_shell(asm_shell, 'minifyWhitespace' in passes, source_map).split('EMSCRIPTEN_FUNCS();');
192
192
  asm_shell_post = asm_shell_post.replace('});', '})');
193
193
  pre += asm_shell_pre + '\n' + start_funcs_marker
@@ -3,7 +3,7 @@ from subprocess import Popen, PIPE, STDOUT
3
3
 
4
4
  TRACK_PROCESS_SPAWNS = True if (os.getenv('EM_BUILD_VERBOSE') and int(os.getenv('EM_BUILD_VERBOSE')) >= 3) else False
5
5
 
6
- def timeout_run(proc, timeout, note='unnamed process', full_output=False):
6
+ def timeout_run(proc, timeout=None, note='unnamed process', full_output=False):
7
7
  start = time.time()
8
8
  if timeout is not None:
9
9
  while time.time() - start < timeout and proc.poll() is None:
Binary file
@@ -1,4 +1,5 @@
1
1
  import tempfile, os, sys, shlex
2
+ import shared
2
3
 
3
4
  # Routes the given cmdline param list in args into a new response file and returns the filename to it.
4
5
  # The returned filename has a suffix '.rsp'.
@@ -9,6 +10,11 @@ def create_response_file(args, directory):
9
10
  args = map(lambda p: p.replace('\\', '\\\\').replace('"', '\\"'), args)
10
11
  response_fd.write('"' + '" "'.join(args) + '"')
11
12
  response_fd.close()
13
+
14
+ # Register the created .rsp file to be automatically cleaned up once this process finishes, so that
15
+ # caller does not have to remember to do it.
16
+ shared.configuration.get_temp_files().note(response_filename)
17
+
12
18
  return response_filename
13
19
 
14
20
  # Reads a response file, and returns the list of cmdline params found in the file.
@@ -18,6 +18,8 @@ JAVA = 'java' # executable
18
18
 
19
19
  TEMP_DIR = '{{{ TEMP }}}'
20
20
 
21
+ CRUNCH = os.path.expanduser(os.getenv('CRUNCH') or 'crunch') # executable
22
+
21
23
  #CLOSURE_COMPILER = '..' # define this to not use the bundled version
22
24
 
23
25
  ########################################################################################################
@@ -1,9 +1,9 @@
1
- import shutil, time, os, sys, json, tempfile, copy, shlex, atexit, subprocess, hashlib, cPickle, re
1
+ import shutil, time, os, sys, json, tempfile, copy, shlex, atexit, subprocess, hashlib, cPickle, re, errno
2
2
  from subprocess import Popen, PIPE, STDOUT
3
3
  from tempfile import mkstemp
4
4
  from distutils.spawn import find_executable
5
5
  import jsrun, cache, tempfiles
6
- from response_file import create_response_file
6
+ import response_file
7
7
  import logging, platform
8
8
 
9
9
  def listify(x):
@@ -41,8 +41,8 @@ class WindowsPopen:
41
41
  # emscripten.py supports reading args from a response file instead of cmdline.
42
42
  # Use .rsp to avoid cmdline length limitations on Windows.
43
43
  if len(args) >= 2 and args[1].endswith("emscripten.py"):
44
- self.response_filename = create_response_file(args[2:], TEMP_DIR)
45
- args = args[0:2] + ['@' + self.response_filename]
44
+ response_filename = response_file.create_response_file(args[2:], TEMP_DIR)
45
+ args = args[0:2] + ['@' + response_filename]
46
46
 
47
47
  try:
48
48
  # Call the process with fixed streams.
@@ -78,13 +78,6 @@ class WindowsPopen:
78
78
  def kill(self):
79
79
  return self.process.kill()
80
80
 
81
- def __del__(self):
82
- try:
83
- # Clean up the temporary response file that was used to spawn this process, so that we don't leave temp files around.
84
- tempfiles.try_delete(self.response_filename)
85
- except:
86
- pass # Mute all exceptions in dtor, particularly if we didn't use a response file, self.response_filename doesn't exist.
87
-
88
81
  __rootpath__ = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
89
82
  def path_from_root(*pathelems):
90
83
  return os.path.join(__rootpath__, *pathelems)
@@ -183,13 +176,28 @@ if WINDOWS:
183
176
  else:
184
177
  logging.StreamHandler.emit = add_coloring_to_emit_ansi(logging.StreamHandler.emit)
185
178
 
186
- # Emscripten configuration is done through the EM_CONFIG environment variable.
187
- # If the string value contained in this environment variable contains newline
188
- # separated definitions, then these definitions will be used to configure
179
+ # Emscripten configuration is done through the --em-config command line option or
180
+ # the EM_CONFIG environment variable. If the specified string value contains newline
181
+ # or semicolon-separated definitions, then these definitions will be used to configure
189
182
  # Emscripten. Otherwise, the string is understood to be a path to a settings
190
183
  # file that contains the required definitions.
191
184
 
192
- EM_CONFIG = os.environ.get('EM_CONFIG')
185
+ try:
186
+ EM_CONFIG = sys.argv[sys.argv.index('--em-config')+1]
187
+ # Emscripten compiler spawns other processes, which can reimport shared.py, so make sure that
188
+ # those child processes get the same configuration file by setting it to the currently active environment.
189
+ os.environ['EM_CONFIG'] = EM_CONFIG
190
+ except:
191
+ EM_CONFIG = os.environ.get('EM_CONFIG')
192
+
193
+ if EM_CONFIG and not os.path.isfile(EM_CONFIG):
194
+ if EM_CONFIG.startswith('-'):
195
+ raise Exception('Passed --em-config without an argument. Usage: --em-config /path/to/.emscripten or --em-config EMSCRIPTEN_ROOT=/path/;LLVM_ROOT=/path;...')
196
+ if not '=' in EM_CONFIG:
197
+ raise Exception('File ' + EM_CONFIG + ' passed to --em-config does not exist!')
198
+ else:
199
+ EM_CONFIG = EM_CONFIG.replace(';', '\n') + '\n'
200
+
193
201
  if not EM_CONFIG:
194
202
  EM_CONFIG = '~/.emscripten'
195
203
  if '\n' in EM_CONFIG:
@@ -284,7 +292,7 @@ def check_node_version():
284
292
  try:
285
293
  node = listify(NODE_JS)
286
294
  actual = Popen(node + ['--version'], stdout=PIPE).communicate()[0].strip()
287
- version = tuple(map(int, actual.replace('v', '').split('.')))
295
+ version = tuple(map(int, actual.replace('v', '').replace('-pre', '').split('.')))
288
296
  if version >= EXPECTED_NODE_VERSION:
289
297
  return True
290
298
  logging.warning('node version appears too old (seeing "%s", expected "%s")' % (actual, 'v' + ('.'.join(map(str, EXPECTED_NODE_VERSION)))))
@@ -314,7 +322,7 @@ def find_temp_directory():
314
322
  # we re-check sanity when the settings are changed)
315
323
  # We also re-check sanity and clear the cache when the version changes
316
324
 
317
- EMSCRIPTEN_VERSION = '1.6.4'
325
+ EMSCRIPTEN_VERSION = '1.7.8'
318
326
 
319
327
  def generate_sanity():
320
328
  return EMSCRIPTEN_VERSION + '|' + get_llvm_target() + '|' + LLVM_ROOT
@@ -323,7 +331,7 @@ def check_sanity(force=False):
323
331
  try:
324
332
  reason = None
325
333
  if not CONFIG_FILE:
326
- if not force: return # config stored directly in EM_CONFIG => skip sanity checks
334
+ return # config stored directly in EM_CONFIG => skip sanity checks
327
335
  else:
328
336
  settings_mtime = os.stat(CONFIG_FILE).st_mtime
329
337
  sanity_file = CONFIG_FILE + '_sanity'
@@ -463,6 +471,18 @@ FILE_PACKAGER = path_from_root('tools', 'file_packager.py')
463
471
 
464
472
  # Temp dir. Create a random one, unless EMCC_DEBUG is set, in which case use TEMP_DIR/emscripten_temp
465
473
 
474
+ def safe_ensure_dirs(dirname):
475
+ try:
476
+ os.makedirs(dirname)
477
+ except os.error, e:
478
+ # Ignore error for already existing dirname
479
+ if e.errno != errno.EEXIST:
480
+ raise e
481
+ # FIXME: Notice that this will result in a false positive,
482
+ # should the dirname be a file! There seems to no way to
483
+ # handle this atomically in Python 2.x.
484
+ # There is an additional option for Python 3.x, though.
485
+
466
486
  class Configuration:
467
487
  def __init__(self, environ=os.environ):
468
488
  self.DEBUG = environ.get('EMCC_DEBUG')
@@ -487,10 +507,9 @@ class Configuration:
487
507
  if self.DEBUG:
488
508
  try:
489
509
  self.EMSCRIPTEN_TEMP_DIR = self.CANONICAL_TEMP_DIR
490
- if not os.path.exists(self.EMSCRIPTEN_TEMP_DIR):
491
- os.makedirs(self.EMSCRIPTEN_TEMP_DIR)
510
+ safe_ensure_dirs(self.EMSCRIPTEN_TEMP_DIR)
492
511
  except Exception, e:
493
- logging.debug(e + 'Could not create canonical temp dir. Check definition of TEMP_DIR in ~/.emscripten')
512
+ logging.error(str(e) + 'Could not create canonical temp dir. Check definition of TEMP_DIR in ~/.emscripten')
494
513
 
495
514
  def get_temp_files(self):
496
515
  return tempfiles.TempFiles(
@@ -633,7 +652,7 @@ def check_engine(engine):
633
652
  try:
634
653
  if not CONFIG_FILE:
635
654
  return True # config stored directly in EM_CONFIG => skip engine check
636
- return 'hello, world!' in run_js(path_from_root('tests', 'hello_world.js'), engine)
655
+ return 'hello, world!' in run_js(path_from_root('src', 'hello_world.js'), engine)
637
656
  except Exception, e:
638
657
  print 'Checking JS engine %s failed. Check %s. Details: %s' % (str(engine), EM_CONFIG, str(e))
639
658
  return False
@@ -922,7 +941,7 @@ class Building:
922
941
 
923
942
 
924
943
  @staticmethod
925
- def build_library(name, build_dir, output_dir, generated_libs, configure=['sh', './configure'], configure_args=[], make=['make'], make_args=['-j', '2'], cache=None, cache_name=None, copy_project=False, env_init={}, source_dir=None, native=False):
944
+ def build_library(name, build_dir, output_dir, generated_libs, configure=['sh', './configure'], configure_args=[], make=['make'], make_args='help', cache=None, cache_name=None, copy_project=False, env_init={}, source_dir=None, native=False):
926
945
  ''' Build a library into a .bc file. We build the .bc file once and cache it for all our tests. (We cache in
927
946
  memory since the test directory is destroyed and recreated for each test. Note that we cache separately
928
947
  for different compilers).
@@ -930,6 +949,8 @@ class Building:
930
949
 
931
950
  if type(generated_libs) is not list: generated_libs = [generated_libs]
932
951
  if source_dir is None: source_dir = path_from_root('tests', name.replace('_native', ''))
952
+ if make_args == 'help':
953
+ make_args = ['-j', str(multiprocessing.cpu_count())]
933
954
 
934
955
  temp_dir = build_dir
935
956
  if copy_project:
@@ -1024,8 +1045,7 @@ class Building:
1024
1045
  try:
1025
1046
  temp_dir = os.path.join(EMSCRIPTEN_TEMP_DIR, 'ar_output_' + str(os.getpid()) + '_' + str(len(temp_dirs)))
1026
1047
  temp_dirs.append(temp_dir)
1027
- if not os.path.exists(temp_dir):
1028
- os.makedirs(temp_dir)
1048
+ safe_ensure_dirs(temp_dir)
1029
1049
  os.chdir(temp_dir)
1030
1050
  contents = filter(lambda x: len(x) > 0, Popen([LLVM_AR, 't', f], stdout=PIPE).communicate()[0].split('\n'))
1031
1051
  #print >> sys.stderr, ' considering archive', f, ':', contents
@@ -1034,9 +1054,9 @@ class Building:
1034
1054
  else:
1035
1055
  for content in contents: # ar will silently fail if the directory for the file does not exist, so make all the necessary directories
1036
1056
  dirname = os.path.dirname(content)
1037
- if dirname and not os.path.exists(dirname):
1038
- os.makedirs(dirname)
1039
- Popen([LLVM_AR, 'x', f], stdout=PIPE).communicate() # if absolute paths, files will appear there. otherwise, in this directory
1057
+ if dirname:
1058
+ safe_ensure_dirs(dirname)
1059
+ Popen([LLVM_AR, 'xo', f], stdout=PIPE).communicate() # if absolute paths, files will appear there. otherwise, in this directory
1040
1060
  contents = map(lambda content: os.path.join(temp_dir, content), contents)
1041
1061
  contents = filter(os.path.exists, map(os.path.abspath, contents))
1042
1062
  added_contents = set()
@@ -1117,14 +1137,16 @@ class Building:
1117
1137
  # @param opt Either an integer, in which case it is the optimization level (-O1, -O2, etc.), or a list of raw
1118
1138
  # optimization passes passed to llvm opt
1119
1139
  @staticmethod
1120
- def llvm_opt(filename, opts):
1140
+ def llvm_opt(filename, opts, out=None):
1121
1141
  if type(opts) is int:
1122
1142
  opts = Building.pick_llvm_opts(opts)
1123
1143
  #opts += ['-debug-pass=Arguments']
1124
1144
  logging.debug('emcc: LLVM opts: ' + str(opts))
1125
- output = Popen([LLVM_OPT, filename] + opts + ['-o', filename + '.opt.bc'], stdout=PIPE).communicate()[0]
1126
- assert os.path.exists(filename + '.opt.bc'), 'Failed to run llvm optimizations: ' + output
1127
- shutil.move(filename + '.opt.bc', filename)
1145
+ target = out or (filename + '.opt.bc')
1146
+ output = Popen([LLVM_OPT, filename] + opts + ['-o', target], stdout=PIPE).communicate()[0]
1147
+ assert os.path.exists(target), 'Failed to run llvm optimizations: ' + output
1148
+ if not out:
1149
+ shutil.move(filename + '.opt.bc', filename)
1128
1150
 
1129
1151
  @staticmethod
1130
1152
  def llvm_opts(filename): # deprecated version, only for test runner. TODO: remove
@@ -1214,7 +1236,13 @@ class Building:
1214
1236
  # Run Emscripten
1215
1237
  Settings.RELOOPER = Cache.get_path('relooper.js')
1216
1238
  settings = Settings.serialize()
1217
- compiler_output = jsrun.timeout_run(Popen([PYTHON, EMSCRIPTEN, filename + ('.o.ll' if append_ext else ''), '-o', filename + '.o.js'] + settings + extra_args, stdout=PIPE), None, 'Compiling')
1239
+ args = settings + extra_args
1240
+ if WINDOWS:
1241
+ args = ['@' + response_file.create_response_file(args, TEMP_DIR)]
1242
+ cmdline = [PYTHON, EMSCRIPTEN, filename + ('.o.ll' if append_ext else ''), '-o', filename + '.o.js'] + args
1243
+ if jsrun.TRACK_PROCESS_SPAWNS:
1244
+ logging.info('Executing emscripten.py compiler with cmdline "' + ' '.join(cmdline) + '"')
1245
+ compiler_output = jsrun.timeout_run(Popen(cmdline, stdout=PIPE), None, 'Compiling')
1218
1246
  #print compiler_output
1219
1247
 
1220
1248
  # Detect compilation crashes and errors
@@ -1410,6 +1438,10 @@ class Building:
1410
1438
  @staticmethod
1411
1439
  def ensure_relooper(relooper):
1412
1440
  if os.path.exists(relooper): return
1441
+ if os.environ.get('EMCC_FAST_COMPILER'):
1442
+ logging.debug('not building relooper to js, using it in c++ backend')
1443
+ return
1444
+
1413
1445
  Cache.ensure()
1414
1446
  curr = os.getcwd()
1415
1447
  try:
@@ -1508,7 +1540,29 @@ class JS:
1508
1540
 
1509
1541
  @staticmethod
1510
1542
  def to_nice_ident(ident): # limited version of the JS function toNiceIdent
1511
- return ident.replace('%', '$').replace('@', '_')
1543
+ return ident.replace('%', '$').replace('@', '_').replace('.', '_')
1544
+
1545
+ @staticmethod
1546
+ def make_initializer(sig, settings=None):
1547
+ settings = settings or Settings
1548
+ if sig == 'i':
1549
+ return '0'
1550
+ elif sig == 'f' and settings.get('PRECISE_F32'):
1551
+ return 'Math_fround(0)'
1552
+ else:
1553
+ return '+0'
1554
+
1555
+ @staticmethod
1556
+ def make_coercion(value, sig, settings=None):
1557
+ settings = settings or Settings
1558
+ if sig == 'i':
1559
+ return value + '|0'
1560
+ elif sig == 'f' and settings.get('PRECISE_F32'):
1561
+ return 'Math_fround(' + value + ')'
1562
+ elif sig == 'd' or sig == 'f':
1563
+ return '+' + value
1564
+ else:
1565
+ return value
1512
1566
 
1513
1567
  @staticmethod
1514
1568
  def make_extcall(sig, named=True):
Binary file