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
@@ -18,8 +18,9 @@ var LLVM = {
18
18
  PHI_REACHERS: set('branch', 'switch', 'invoke', 'indirectbr'),
19
19
  EXTENDS: set('sext', 'zext'),
20
20
  COMPS: set('icmp', 'fcmp'),
21
- CONVERSIONS: set('inttoptr', 'ptrtoint', 'uitofp', 'sitofp', 'fptosi', 'fptoui'),
21
+ CONVERSIONS: set('inttoptr', 'ptrtoint', 'uitofp', 'sitofp', 'fptosi', 'fptoui', 'fpext', 'fptrunc'),
22
22
  INTRINSICS_32: set('_llvm_memcpy_p0i8_p0i8_i64', '_llvm_memmove_p0i8_p0i8_i64', '_llvm_memset_p0i8_i64'), // intrinsics that need args converted to i32 in USE_TYPED_ARRAYS == 2
23
+ MATHOP_IGNORABLES: set('exact', 'nnan', 'ninf', 'nsz', 'arcp', 'fast'),
23
24
  };
24
25
  LLVM.GLOBAL_MODIFIERS = set(keys(LLVM.LINKAGES).concat(['constant', 'global', 'hidden']));
25
26
 
@@ -253,31 +254,46 @@ var Functions = {
253
254
 
254
255
  aliases: {}, // in shared modules (MAIN_MODULE or SHARED_MODULE), a list of aliases for functions that have them
255
256
 
257
+ getSignatureLetter: function(type) {
258
+ switch(type) {
259
+ case 'float': return 'f';
260
+ case 'double': return 'd';
261
+ case 'void': return 'v';
262
+ default: return 'i';
263
+ }
264
+ },
265
+
266
+ getSignatureType: function(letter) {
267
+ switch(letter) {
268
+ case 'v': return 'void';
269
+ case 'i': return 'i32';
270
+ case 'f': return 'float';
271
+ case 'd': return 'double';
272
+ default: throw 'what is this sig? ' + sig;
273
+ }
274
+ },
275
+
256
276
  getSignature: function(returnType, argTypes, hasVarArgs) {
257
- var sig = returnType == 'void' ? 'v' : (isIntImplemented(returnType) ? 'i' : 'f');
277
+ var sig = Functions.getSignatureLetter(returnType);
258
278
  for (var i = 0; i < argTypes.length; i++) {
259
279
  var type = argTypes[i];
260
280
  if (!type) break; // varargs
261
281
  if (type in Runtime.FLOAT_TYPES) {
262
- sig += 'f';
282
+ sig += Functions.getSignatureLetter(type);
263
283
  } else {
264
284
  var chunks = getNumIntChunks(type);
265
- for (var j = 0; j < chunks; j++) sig += 'i';
285
+ if (chunks > 0) {
286
+ for (var j = 0; j < chunks; j++) sig += 'i';
287
+ } else if (type !== '...') {
288
+ // some special type like a SIMD vector (anything but varargs, which we handle below)
289
+ sig += Functions.getSignatureLetter(type);
290
+ }
266
291
  }
267
292
  }
268
293
  if (hasVarArgs) sig += 'i';
269
294
  return sig;
270
295
  },
271
296
 
272
- getSignatureReturnType: function(sig) {
273
- switch(sig[0]) {
274
- case 'v': return 'void';
275
- case 'i': return 'i32';
276
- case 'f': return 'double';
277
- default: throw 'what is this sig? ' + sig;
278
- }
279
- },
280
-
281
297
  // Mark a function as needing indexing. Python will coordinate them all
282
298
  getIndex: function(ident, sig) {
283
299
  var ret;
@@ -331,7 +347,7 @@ var Functions = {
331
347
  // Resolve multi-level aliases all the way down
332
348
  while (1) {
333
349
  var varData = Variables.globals[table[i]];
334
- if (!(varData && varData.resolvedAlias && varData.resolvedAlias.indexOf('FUNCTION_TABLE_OFFSET') < 0)) break;
350
+ if (!(varData && varData.resolvedAlias && !/(FUNCTION_TABLE_OFFSET|F_BASE_)/.test(varData.resolvedAlias))) break;
335
351
  table[i] = table[+varData.resolvedAlias || eval(varData.resolvedAlias)]; // might need to eval to turn (6) into 6
336
352
  }
337
353
  // Resolve library aliases
@@ -350,17 +366,15 @@ var Functions = {
350
366
  if (!wrapped[curr]) {
351
367
  var args = '', arg_coercions = '', call = short + '(', retPre = '', retPost = '';
352
368
  if (t[0] != 'v') {
353
- if (t[0] == 'i') {
354
- retPre = 'return ';
355
- retPost = '|0';
356
- } else {
357
- retPre = 'return +';
358
- }
369
+ var temp = asmFFICoercion('X', Functions.getSignatureType(t[0])).split('X');
370
+ retPre = 'return ' + temp[0];
371
+ retPost = temp[1];
359
372
  }
360
373
  for (var j = 1; j < t.length; j++) {
361
374
  args += (j > 1 ? ',' : '') + 'a' + j;
362
- arg_coercions += 'a' + j + '=' + asmCoercion('a' + j, t[j] != 'i' ? 'float' : 'i32') + ';';
363
- call += (j > 1 ? ',' : '') + asmCoercion('a' + j, t[j] != 'i' ? 'float' : 'i32');
375
+ var type = Functions.getSignatureType(t[j]);
376
+ arg_coercions += 'a' + j + '=' + asmCoercion('a' + j, type) + ';';
377
+ call += (j > 1 ? ',' : '') + asmCoercion('a' + j, type === 'float' ? 'double' : type); // ffi arguments must be doubles if they are floats
364
378
  }
365
379
  call += ')';
366
380
  if (short == '_setjmp') printErr('WARNING: setjmp used via a function pointer. If this is for libc setjmp (not something of your own with the same name), it will break things');
@@ -415,6 +429,26 @@ var LibraryManager = {
415
429
  eval(processMacros(preprocess(read(libraries[i]))));
416
430
  }
417
431
 
432
+ /*
433
+ // export code for CallHandlers.h
434
+ printErr('============================');
435
+ for (var x in this.library) {
436
+ var y = this.library[x];
437
+ if (typeof y === 'string' && x.indexOf('__sig') < 0 && x.indexOf('__postset') < 0 && y.indexOf(' ') < 0) {
438
+ printErr('DEF_REDIRECT_HANDLER(' + x + ', ' + y + ');');
439
+ }
440
+ }
441
+ printErr('============================');
442
+ for (var x in this.library) {
443
+ var y = this.library[x];
444
+ if (typeof y === 'string' && x.indexOf('__sig') < 0 && x.indexOf('__postset') < 0 && y.indexOf(' ') < 0) {
445
+ printErr(' SETUP_CALL_HANDLER(' + x + ');');
446
+ }
447
+ }
448
+ printErr('============================');
449
+ // end export code for CallHandlers.h
450
+ */
451
+
418
452
  this.loaded = true;
419
453
  },
420
454
 
@@ -474,6 +508,11 @@ var PassManager = {
474
508
  print('\n//FORWARDED_DATA:' + JSON.stringify({
475
509
  Functions: { tables: Functions.tables }
476
510
  }));
511
+ } else if (phase == 'glue') {
512
+ print('\n//FORWARDED_DATA:' + JSON.stringify({
513
+ Functions: Functions,
514
+ EXPORTED_FUNCTIONS: EXPORTED_FUNCTIONS
515
+ }));
477
516
  }
478
517
  },
479
518
  load: function(json) {
@@ -487,6 +526,7 @@ var PassManager = {
487
526
  for (var i in data.Functions) {
488
527
  Functions[i] = data.Functions[i];
489
528
  }
529
+ EXPORTED_FUNCTIONS = data.EXPORTED_FUNCTIONS;
490
530
  /*
491
531
  print('\n//LOADED_DATA:' + phase + ':' + JSON.stringify({
492
532
  Types: Types,
@@ -157,6 +157,10 @@ function isStructType(type) {
157
157
  return type[0] == '%';
158
158
  }
159
159
 
160
+ function isVectorType(type) {
161
+ return type[type.length-1] === '>';
162
+ }
163
+
160
164
  function isStructuralType(type) {
161
165
  return /^{ ?[^}]* ?}$/.test(type); // { i32, i8 } etc. - anonymous struct types
162
166
  }
@@ -215,8 +219,22 @@ function isIdenticallyImplemented(type1, type2) {
215
219
  }
216
220
 
217
221
  function isIllegalType(type) {
218
- var bits = getBits(type);
219
- return bits > 0 && (bits >= 64 || !isPowerOfTwo(bits));
222
+ switch (type) {
223
+ case 'i1':
224
+ case 'i8':
225
+ case 'i16':
226
+ case 'i32':
227
+ case 'float':
228
+ case 'double':
229
+ case 'rawJS':
230
+ case '<2 x float>':
231
+ case '<4 x float>':
232
+ case '<2 x i32>':
233
+ case '<4 x i32>':
234
+ case 'void': return false;
235
+ }
236
+ if (!type || type[type.length-1] === '*') return false;
237
+ return true;
220
238
  }
221
239
 
222
240
  function isVoidType(type) {
@@ -287,6 +305,9 @@ function getReturnType(type) {
287
305
  if (pointingLevels(type) > 1) return '*'; // the type of a call can be either the return value, or the entire function. ** or more means it is a return value
288
306
  var lastOpen = type.lastIndexOf('(');
289
307
  if (lastOpen > 0) {
308
+ // handle things like void (i32)* (i32, void (i32)*)*
309
+ var closeStar = type.indexOf(')*');
310
+ if (closeStar > 0 && closeStar < type.length-2) lastOpen = closeStar+3;
290
311
  return type.substr(0, lastOpen-1);
291
312
  }
292
313
  return type;
@@ -328,28 +349,29 @@ function getVectorSize(type) {
328
349
  return parseInt(type.substring(1, type.indexOf(' ')));
329
350
  }
330
351
 
331
- function getVectorBaseType(type) {
352
+ function getVectorNativeType(type) {
332
353
  Types.usesSIMD = true;
333
354
  switch (type) {
334
355
  case '<2 x float>':
335
356
  case '<4 x float>': return 'float';
336
357
  case '<2 x i32>':
337
- case '<4 x i32>': return 'uint';
358
+ case '<4 x i32>': return 'i32';
338
359
  default: throw 'unknown vector type ' + type;
339
360
  }
340
361
  }
341
362
 
342
- function getVectorNativeType(type) {
343
- Types.usesSIMD = true;
363
+ function getSIMDName(type) {
344
364
  switch (type) {
345
- case '<2 x float>':
346
- case '<4 x float>': return 'float';
347
- case '<2 x i32>':
348
- case '<4 x i32>': return 'i32';
349
- default: throw 'unknown vector type ' + type;
365
+ case 'i32': return 'int';
366
+ case 'float': return 'float';
367
+ default: throw 'getSIMDName ' + type;
350
368
  }
351
369
  }
352
370
 
371
+ function getVectorBaseType(type) {
372
+ return getSIMDName(getVectorNativeType(type));
373
+ }
374
+
353
375
  function addIdent(token) {
354
376
  token.ident = token.text;
355
377
  return token;
@@ -465,26 +487,13 @@ function parseParamTokens(params) {
465
487
  Types.needAnalysis[ret[ret.length-1].type] = 0;
466
488
  anonymousIndex ++;
467
489
  }
468
- } else if (segment[1].text in PARSABLE_LLVM_FUNCTIONS) {
469
- ret.push(parseLLVMFunctionCall(segment));
470
- } else if (segment[1].text === 'blockaddress') {
471
- ret.push(parseBlockAddress(segment));
472
- } else if (segment[1].type && segment[1].type == '{') {
473
- ret.push(parseLLVMSegment(segment));
474
490
  } else {
475
491
  if (segment[2] && segment[2].text == 'to') { // part of bitcast params
476
492
  segment = segment.slice(0, 2);
477
493
  }
478
- while (segment.length > 2) {
479
- segment[0].text += segment[1].text;
480
- segment.splice(1, 1); // TODO: merge tokens nicely
481
- }
482
- ret.push({
483
- intertype: 'value',
484
- type: segment[0].text,
485
- ident: toNiceIdent(parseNumerical(segment[1].text, segment[0].text))
486
- });
487
- Types.needAnalysis[removeAllPointing(ret[ret.length-1].type)] = 0;
494
+ var parsed = parseLLVMSegment(segment);
495
+ if (parsed.intertype === 'value' && !isIllegalType(parsed.type)) parsed.ident = parseNumerical(parsed.ident, parsed.type);
496
+ ret.push(parsed);
488
497
  }
489
498
  ret[ret.length-1].byVal = byVal;
490
499
  }
@@ -558,25 +567,6 @@ function sortGlobals(globals) {
558
567
  });
559
568
  }
560
569
 
561
- function finalizeParam(param) {
562
- if (param.intertype in PARSABLE_LLVM_FUNCTIONS) {
563
- return finalizeLLVMFunctionCall(param);
564
- } else if (param.intertype === 'blockaddress') {
565
- return finalizeBlockAddress(param);
566
- } else if (param.intertype === 'jsvalue') {
567
- return param.ident;
568
- } else {
569
- if (param.type == 'i64' && USE_TYPED_ARRAYS == 2) {
570
- return parseI64Constant(param.ident);
571
- }
572
- var ret = toNiceIdent(param.ident);
573
- if (ret in Variables.globals) {
574
- ret = makeGlobalUse(ret);
575
- }
576
- return ret;
577
- }
578
- }
579
-
580
570
  // Segment ==> Parameter
581
571
  function parseLLVMSegment(segment) {
582
572
  var type;
@@ -613,10 +603,11 @@ function parseLLVMSegment(segment) {
613
603
  type = segment[0].text;
614
604
  if (type[type.length-1] === '>' && segment[1].text[0] === '<') {
615
605
  // vector literal
606
+ var nativeType = getVectorNativeType(type);
616
607
  return {
617
608
  intertype: 'vector',
618
609
  idents: splitTokenList(segment[1].tokens).map(function(pair) {
619
- return pair[1].text;
610
+ return parseNumerical(pair[1].text, nativeType);
620
611
  }),
621
612
  type: type
622
613
  };
@@ -639,6 +630,8 @@ function cleanSegment(segment) {
639
630
 
640
631
  var MATHOPS = set(['add', 'sub', 'sdiv', 'udiv', 'mul', 'icmp', 'zext', 'urem', 'srem', 'fadd', 'fsub', 'fmul', 'fdiv', 'fcmp', 'frem', 'uitofp', 'sitofp', 'fpext', 'fptrunc', 'fptoui', 'fptosi', 'trunc', 'sext', 'select', 'shl', 'shr', 'ashl', 'ashr', 'lshr', 'lshl', 'xor', 'or', 'and', 'ptrtoint', 'inttoptr']);
641
632
 
633
+ var JS_MATH_BUILTINS = set(['Math_sin', 'Math_cos', 'Math_tan', 'Math_asin', 'Math_acos', 'Math_atan', 'Math_ceil', 'Math_floor', 'Math_exp', 'Math_log', 'Math_sqrt']);
634
+
642
635
  var PARSABLE_LLVM_FUNCTIONS = set('getelementptr', 'bitcast');
643
636
  mergeInto(PARSABLE_LLVM_FUNCTIONS, MATHOPS);
644
637
 
@@ -798,8 +791,8 @@ function splitI64(value, floatConversion) {
798
791
  var high = makeInlineCalculation(
799
792
  asmCoercion('Math_abs(VALUE)', 'double') + ' >= ' + asmEnsureFloat('1', 'double') + ' ? ' +
800
793
  '(VALUE > ' + asmEnsureFloat('0', 'double') + ' ? ' +
801
- asmCoercion('Math_min(' + asmCoercion('Math_floor((VALUE)/' + asmEnsureFloat(4294967296, 'float') + ')', 'double') + ', ' + asmEnsureFloat(4294967295, 'float') + ')', 'i32') + '>>>0' +
802
- ' : ' + asmFloatToInt(asmCoercion('Math_ceil((VALUE - +((' + asmFloatToInt('VALUE') + ')>>>0))/' + asmEnsureFloat(4294967296, 'float') + ')', 'double')) + '>>>0' +
794
+ asmCoercion('Math_min(' + asmCoercion('Math_floor((VALUE)/' + asmEnsureFloat(4294967296, 'double') + ')', 'double') + ', ' + asmEnsureFloat(4294967295, 'double') + ')', 'i32') + '>>>0' +
795
+ ' : ' + asmFloatToInt(asmCoercion('Math_ceil((VALUE - +((' + asmFloatToInt('VALUE') + ')>>>0))/' + asmEnsureFloat(4294967296, 'double') + ')', 'double')) + '>>>0' +
803
796
  ')' +
804
797
  ' : 0',
805
798
  value,
@@ -991,6 +984,12 @@ function parseLLVMString(str) {
991
984
  return ret;
992
985
  }
993
986
 
987
+ function expandLLVMString(str) {
988
+ return str.replace(/\\../g, function(m) {
989
+ return String.fromCharCode(parseInt(m.substr(1), '16'));
990
+ });
991
+ }
992
+
994
993
  function getLabelIds(labels) {
995
994
  return labels.map(function(label) { return label.ident });
996
995
  }
@@ -1009,11 +1008,9 @@ function getOldLabel(label) {
1009
1008
  }
1010
1009
 
1011
1010
  function calcAllocatedSize(type) {
1012
- if (pointingLevels(type) == 0 && isStructType(type)) {
1013
- return Types.types[type].flatSize; // makeEmptyStruct(item.allocatedType).length;
1014
- } else {
1015
- return Runtime.getNativeTypeSize(type); // We can really get away with '1', though, at least on the stack...
1016
- }
1011
+ var ret = Runtime.getNativeTypeSize(type);
1012
+ if (ret) return ret;
1013
+ return Types.types[type].flatSize; // known type
1017
1014
  }
1018
1015
 
1019
1016
  // Generates the type signature for a structure, for each byte, the type that is there.
@@ -1173,32 +1170,37 @@ function makeVarDef(js) {
1173
1170
  return js;
1174
1171
  }
1175
1172
 
1173
+ function ensureDot(value) {
1174
+ value = value.toString();
1175
+ // if already dotted, or Infinity or NaN, nothing to do here
1176
+ // if smaller than 1 and running js opts, we always need to force a coercion (0.001 will turn into 1e-3, which has no .)
1177
+ if ((value.indexOf('.') >= 0 || /[IN]/.test(value)) && (!RUNNING_JS_OPTS || Math.abs(value) >= 1)) return value;
1178
+ if (RUNNING_JS_OPTS) return '(+' + value + ')'; // JS optimizer will run, we must do +x, and it will be corrected later
1179
+ var e = value.indexOf('e');
1180
+ if (e < 0) return value + '.0';
1181
+ return value.substr(0, e) + '.0' + value.substr(e);
1182
+ }
1183
+
1176
1184
  function asmEnsureFloat(value, type) { // ensures that a float type has either 5.5 (clearly a float) or +5 (float due to asm coercion)
1177
1185
  if (!ASM_JS) return value;
1178
- // coerce if missing a '.', or if smaller than 1, so could be 1e-5 which has no .
1179
- if (type in Runtime.FLOAT_TYPES && isNumber(value) && (value.toString().indexOf('.') < 0 || Math.abs(value) < 1)) {
1180
- if (RUNNING_JS_OPTS) {
1181
- return '(+' + value + ')'; // JS optimizer will run, we must do +x, and it will be corrected later
1182
- } else {
1183
- // ensure a .
1184
- value = value.toString();
1185
- if (value.indexOf('.') >= 0 || /[IN]/.test(value)) return value; // if already dotted, or Infinity or NaN, nothing to do here
1186
- var e = value.indexOf('e');
1187
- if (e < 0) return value + '.0';
1188
- return value.substr(0, e) + '.0' + value.substr(e);
1189
- }
1186
+ if (!isNumber(value)) return value;
1187
+ if (PRECISE_F32 && type === 'float') {
1188
+ // normally ok to just emit Math_fround(0), but if the constant is large we may need a .0 (if it can't fit in an int)
1189
+ if (value == 0) return 'Math_fround(0)';
1190
+ value = ensureDot(value);
1191
+ return 'Math_fround(' + value + ')';
1192
+ }
1193
+ if (type in Runtime.FLOAT_TYPES) {
1194
+ return ensureDot(value);
1190
1195
  } else {
1191
1196
  return value;
1192
1197
  }
1193
1198
  }
1194
1199
 
1195
- function asmInitializer(type, impl) {
1200
+ function asmInitializer(type) {
1196
1201
  if (type in Runtime.FLOAT_TYPES) {
1197
- if (RUNNING_JS_OPTS) {
1198
- return '+0';
1199
- } else {
1200
- return '.0';
1201
- }
1202
+ if (PRECISE_F32 && type === 'float') return 'Math_fround(0)';
1203
+ return RUNNING_JS_OPTS ? '+0' : '.0';
1202
1204
  } else {
1203
1205
  return '0';
1204
1206
  }
@@ -1219,7 +1221,11 @@ function asmCoercion(value, type, signedness) {
1219
1221
  value = '(' + value + ')|0';
1220
1222
  }
1221
1223
  }
1222
- return '(+(' + value + '))';
1224
+ if (PRECISE_F32 && type === 'float') {
1225
+ return 'Math_fround(' + value + ')';
1226
+ } else {
1227
+ return '(+(' + value + '))';
1228
+ }
1223
1229
  }
1224
1230
  } else {
1225
1231
  return '((' + value + ')|0)';
@@ -1448,7 +1454,7 @@ function makeSetValues(ptr, pos, value, type, num, align) {
1448
1454
  // If we don't know how to handle this at compile-time, or handling it is best done in a large amount of code, call memset
1449
1455
  // TODO: optimize the case of numeric num but non-numeric value
1450
1456
  if (!isNumber(num) || !isNumber(value) || (parseInt(num)/align >= UNROLL_LOOP_MAX)) {
1451
- return '_memset(' + asmCoercion(getFastValue(ptr, '+', pos), 'i32') + ', ' + asmCoercion(value, 'i32') + ', ' + asmCoercion(num, 'i32') + ')';
1457
+ return '_memset(' + asmCoercion(getFastValue(ptr, '+', pos), 'i32') + ', ' + asmCoercion(value, 'i32') + ', ' + asmCoercion(num, 'i32') + ')|0';
1452
1458
  }
1453
1459
  num = parseInt(num);
1454
1460
  value = parseInt(value);
@@ -1809,7 +1815,7 @@ function makeGetSlabs(ptr, type, allowMultiple, unsigned) {
1809
1815
  switch(type) {
1810
1816
  case 'i1': case 'i8': return [unsigned ? 'HEAPU8' : 'HEAP8']; break;
1811
1817
  case 'i16': return [unsigned ? 'HEAPU16' : 'HEAP16']; break;
1812
- case '<4 x i32>': case 'uint':
1818
+ case '<4 x i32>':
1813
1819
  case 'i32': case 'i64': return [unsigned ? 'HEAPU32' : 'HEAP32']; break;
1814
1820
  case 'double': {
1815
1821
  if (TARGET_LE32) return ['HEAPF64']; // in le32, we do have the ability to assume 64-bit alignment
@@ -2002,6 +2008,8 @@ function finalizeLLVMParameter(param, noIndexizeFunctions) {
2002
2008
  } else if (param.ident == 'zeroinitializer') {
2003
2009
  if (isStructType(param.type)) {
2004
2010
  return makeLLVMStruct(zeros(Types.types[param.type].fields.length));
2011
+ } else if (isVectorType(param.type)) {
2012
+ return ensureVector(0, getVectorBaseType(param.type));
2005
2013
  } else {
2006
2014
  return '0';
2007
2015
  }
@@ -2024,7 +2032,7 @@ function finalizeLLVMParameter(param, noIndexizeFunctions) {
2024
2032
  } else if (param.intertype == 'mathop') {
2025
2033
  return processMathop(param);
2026
2034
  } else if (param.intertype === 'vector') {
2027
- return 'float32x4(' + param.idents.join(',') + ')';
2035
+ return getVectorBaseType(param.type) + '32x4(' + param.idents.join(',') + ')';
2028
2036
  } else {
2029
2037
  throw 'invalid llvm parameter: ' + param.intertype;
2030
2038
  }
@@ -2051,7 +2059,7 @@ function makeSignOp(value, type, op, force, ignore) {
2051
2059
  if (isPointerType(type)) type = 'i32'; // Pointers are treated as 32-bit ints
2052
2060
  if (!value) return value;
2053
2061
  var bits, full;
2054
- if (type in Runtime.INT_TYPES) {
2062
+ if (type[0] === 'i') {
2055
2063
  bits = parseInt(type.substr(1));
2056
2064
  full = op + 'Sign(' + value + ', ' + bits + ', ' + Math.floor(ignore || correctSpecificSign()) + ')';
2057
2065
  // Always sign/unsign constants at compile time, regardless of CHECK/CORRECT
@@ -2060,7 +2068,7 @@ function makeSignOp(value, type, op, force, ignore) {
2060
2068
  }
2061
2069
  }
2062
2070
  if ((ignore || !correctSigns()) && !CHECK_SIGNS && !force) return value;
2063
- if (type in Runtime.INT_TYPES) {
2071
+ if (type[0] === 'i') {
2064
2072
  // this is an integer, but not a number (or we would have already handled it)
2065
2073
  // shortcuts
2066
2074
  if (!CHECK_SIGNS || ignore) {
@@ -2133,14 +2141,14 @@ function makeRounding(value, bits, signed, floatConversion) {
2133
2141
  }
2134
2142
  }
2135
2143
 
2136
- function makeIsNaN(value) {
2137
- if (ASM_JS) return makeInlineCalculation('((VALUE) != (VALUE))', value, 'tempDouble');
2144
+ function makeIsNaN(value, type) {
2145
+ if (ASM_JS) return makeInlineCalculation('((VALUE) != (VALUE))', value, type === 'float' ? 'tempFloat' : 'tempDouble');
2138
2146
  return 'isNaN(' + value + ')';
2139
2147
  }
2140
2148
 
2141
2149
  function makeFloat(value, type) {
2142
- if (TO_FLOAT32 && type == 'float') {
2143
- return 'Math_toFloat32(' + value + ')';
2150
+ if (PRECISE_F32 && type == 'float') {
2151
+ return 'Math_fround(' + value + ')';
2144
2152
  }
2145
2153
  return value;
2146
2154
  }
@@ -2257,8 +2265,8 @@ function processMathop(item) {
2257
2265
  case 'lshr': {
2258
2266
  throw 'shifts should have been legalized!';
2259
2267
  }
2260
- case 'uitofp': case 'sitofp': return RuntimeGenerator.makeBigInt(low1, high1, op[0] == 'u');
2261
- case 'fptoui': case 'fptosi': return finish(splitI64(idents[0], true));
2268
+ case 'uitofp': case 'sitofp': return makeFloat(RuntimeGenerator.makeBigInt(low1, high1, op[0] == 'u'), item.type);
2269
+ case 'fptoui': case 'fptosi': return finish(splitI64(asmCoercion(idents[0], 'double'), true)); // coerce to double before conversion to i64
2262
2270
  case 'icmp': {
2263
2271
  switch (variant) {
2264
2272
  case 'uge': return '((' + high1 + '>>>0) >= (' + high2 + '>>>0)) & ((((' + high1 + '>>>0) > (' + high2 + '>>>0)) | ' +
@@ -2287,7 +2295,7 @@ function processMathop(item) {
2287
2295
  case 'trunc': {
2288
2296
  return '((' + idents[0] + '[0]) & ' + (Math.pow(2, bitsLeft)-1) + ')';
2289
2297
  }
2290
- case 'select': return idents[0] + ' ? ' + makeCopyI64(idents[1]) + ' : ' + makeCopyI64(idents[2]);
2298
+ case 'select': return '(' + idents[0] + ' ? ' + makeCopyI64(idents[1]) + ' : ' + makeCopyI64(idents[2]) + ')';;
2291
2299
  case 'ptrtoint': return makeI64(idents[0], 0);
2292
2300
  case 'inttoptr': {
2293
2301
  var m = /\(?\[(\d+),\d+\]\)?/.exec(idents[0]);
@@ -2364,26 +2372,28 @@ function processMathop(item) {
2364
2372
  // vector/SIMD operation
2365
2373
  Types.usesSIMD = true;
2366
2374
  switch (op) {
2367
- case 'fadd': return 'SIMD.add(' + idents[0] + ',' + idents[1] + ')';
2368
- case 'fsub': return 'SIMD.sub(' + idents[0] + ',' + idents[1] + ')';
2369
- case 'fmul': return 'SIMD.mul(' + idents[0] + ',' + idents[1] + ')';
2370
- case 'fdiv': return 'SIMD.div(' + idents[0] + ',' + idents[1] + ')';
2371
- case 'add' : return 'SIMD.addu32(' + idents[0] + ',' + idents[1] + ')';
2372
- case 'sub' : return 'SIMD.subu32(' + idents[0] + ',' + idents[1] + ')';
2373
- case 'mul' : return 'SIMD.mulu32(' + idents[0] + ',' + idents[1] + ')';
2374
- case 'udiv': return 'SIMD.divu32(' + idents[0] + ',' + idents[1] + ')';
2375
+ case 'fadd': return 'SIMD.float32x4.add(' + idents[0] + ',' + idents[1] + ')';
2376
+ case 'fsub': return 'SIMD.float32x4.sub(' + idents[0] + ',' + idents[1] + ')';
2377
+ case 'fmul': return 'SIMD.float32x4.mul(' + idents[0] + ',' + idents[1] + ')';
2378
+ case 'fdiv': return 'SIMD.float32x4.div(' + idents[0] + ',' + idents[1] + ')';
2379
+ case 'add' : return 'SIMD.int32x4.add(' + idents[0] + ',' + idents[1] + ')';
2380
+ case 'sub' : return 'SIMD.int32x4.sub(' + idents[0] + ',' + idents[1] + ')';
2381
+ case 'mul' : return 'SIMD.int32x4.mul(' + idents[0] + ',' + idents[1] + ')';
2375
2382
  case 'bitcast': {
2376
2383
  var inType = item.params[0].type;
2377
2384
  var outType = item.type;
2378
2385
  if (inType === '<4 x float>') {
2379
2386
  assert(outType === '<4 x i32>');
2380
- return 'SIMD.float32x4BitsToUint32x4(' + idents[0] + ')';
2387
+ return 'SIMD.float32x4.bitsToInt32x4(' + idents[0] + ')';
2381
2388
  } else {
2382
2389
  assert(inType === '<4 x i32>');
2383
2390
  assert(outType === '<4 x float>');
2384
- return 'SIMD.uint32x4BitsToFloat32x4(' + idents[0] + ')';
2391
+ return 'SIMD.int32x4.bitsToFloat32x4(' + idents[0] + ')';
2385
2392
  }
2386
2393
  }
2394
+ case 'and': return 'SIMD.int32x4.and(' + idents[0] + ',' + idents[1] + ')';
2395
+ case 'or': return 'SIMD.int32x4.or(' + idents[0] + ',' + idents[1] + ')';
2396
+ case 'xor': return 'SIMD.int32x4.xor(' + idents[0] + ',' + idents[1] + ')';
2387
2397
  default: throw 'vector op todo: ' + dump(item);
2388
2398
  }
2389
2399
  }
@@ -2439,12 +2449,17 @@ function processMathop(item) {
2439
2449
  case 'fdiv': return makeFloat(getFastValue(idents[0], '/', idents[1], item.type), item.type);
2440
2450
  case 'fmul': return makeFloat(getFastValue(idents[0], '*', idents[1], item.type), item.type);
2441
2451
  case 'frem': return makeFloat(getFastValue(idents[0], '%', idents[1], item.type), item.type);
2442
- case 'uitofp': case 'sitofp': return asmCoercion(idents[0], 'double', op[0]);
2452
+ case 'uitofp': case 'sitofp': return asmCoercion(idents[0], item.type, op[0]);
2443
2453
  case 'fptoui': case 'fptosi': return makeRounding(idents[0], bitsLeft, op === 'fptosi', true);
2444
2454
 
2445
2455
  // TODO: We sometimes generate false instead of 0, etc., in the *cmps. It seemed slightly faster before, but worth rechecking
2446
2456
  // Note that with typed arrays, these become 0 when written. So that is a potential difference with non-typed array runs.
2447
2457
  case 'icmp': {
2458
+ // unsigned coercions can be (X&Y), which is not a valid asm coercion for comparisons
2459
+ if (ASM_JS && variant[0] === 'u') {
2460
+ if (idents[0].indexOf('>>>') < 0) idents[0] = '((' + idents[0] + ')>>>0)';
2461
+ if (idents[1].indexOf('>>>') < 0) idents[1] = '((' + idents[1] + ')>>>0)';
2462
+ }
2448
2463
  switch (variant) {
2449
2464
  case 'uge': case 'sge': return idents[0] + '>=' + idents[1];
2450
2465
  case 'ule': case 'sle': return idents[0] + '<=' + idents[1];
@@ -2471,8 +2486,8 @@ function processMathop(item) {
2471
2486
  case 'ult': case 'olt': return idents[0] + '<' + idents[1];
2472
2487
  case 'une': case 'one': return idents[0] + '!=' + idents[1];
2473
2488
  case 'ueq': case 'oeq': return idents[0] + '==' + idents[1];
2474
- case 'ord': return '!' + makeIsNaN(idents[0]) + '&!' + makeIsNaN(idents[1]);
2475
- case 'uno': return makeIsNaN(idents[0]) + '|' + makeIsNaN(idents[1]);
2489
+ case 'ord': return '!' + makeIsNaN(idents[0], paramTypes[0]) + '&!' + makeIsNaN(idents[1], paramTypes[0]);
2490
+ case 'uno': return makeIsNaN(idents[0], paramTypes[0]) + '|' + makeIsNaN(idents[1], paramTypes[0]);
2476
2491
  case 'true': return '1';
2477
2492
  default: throw 'Unknown fcmp variant: ' + variant;
2478
2493
  }
@@ -2486,9 +2501,16 @@ function processMathop(item) {
2486
2501
  }
2487
2502
  // otherwise, fall through
2488
2503
  }
2489
- case 'fpext': case 'sext': return idents[0];
2490
- case 'fptrunc': return idents[0];
2491
- case 'select': return idents[0] + '?' + asmEnsureFloat(idents[1], item.type) + ':' + asmEnsureFloat(idents[2], item.type);
2504
+ case 'sext': return idents[0];
2505
+ case 'fpext': {
2506
+ if (PRECISE_F32) return '+(' + idents[0] + ')';
2507
+ return idents[0];
2508
+ }
2509
+ case 'fptrunc': {
2510
+ if (PRECISE_F32) return 'Math_fround(' + idents[0] + ')';
2511
+ return idents[0];
2512
+ }
2513
+ case 'select': return '(' + idents[0] + '?' + asmEnsureFloat(idents[1], item.type) + ':' + asmEnsureFloat(idents[2], item.type) + ')';
2492
2514
  case 'ptrtoint': case 'inttoptr': {
2493
2515
  var ret = '';
2494
2516
  if (QUANTUM_SIZE == 1) {
@@ -2675,6 +2697,17 @@ var simdLane = ['x', 'y', 'z', 'w'];
2675
2697
 
2676
2698
  function ensureVector(ident, base) {
2677
2699
  Types.usesSIMD = true;
2678
- return ident == 0 ? base + '32x4.zero()' : ident;
2700
+ return ident == 0 ? base + '32x4.splat(0)' : ident;
2701
+ }
2702
+
2703
+ function ensureValidFFIType(type) {
2704
+ return type === 'float' ? 'double' : type; // ffi does not tolerate float XXX
2705
+ }
2706
+
2707
+ // FFI return values must arrive as doubles, and we can force them to floats afterwards
2708
+ function asmFFICoercion(value, type) {
2709
+ value = asmCoercion(value, ensureValidFFIType(type));
2710
+ if (PRECISE_F32 && type === 'float') value = asmCoercion(value, 'float');
2711
+ return value;
2679
2712
  }
2680
2713
 
@@ -33,12 +33,11 @@ ExitStatus.prototype.constructor = ExitStatus;
33
33
  var initialStackTop;
34
34
  var preloadStartTime = null;
35
35
  var calledMain = false;
36
- var calledRun = false;
37
36
 
38
37
  dependenciesFulfilled = function runCaller() {
39
38
  // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
40
- if (!calledRun && shouldRunNow) run();
41
- if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
39
+ if (!Module['calledRun'] && shouldRunNow) run();
40
+ if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
42
41
  }
43
42
 
44
43
  Module['callMain'] = Module.callMain = function callMain(args) {
@@ -128,7 +127,7 @@ function run(args) {
128
127
 
129
128
  preMain();
130
129
 
131
- calledRun = true;
130
+ Module['calledRun'] = true;
132
131
  if (Module['_main'] && shouldRunNow) {
133
132
  Module['callMain'](args);
134
133
  }