webruby 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
  }