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.
- checksums.yaml +4 -4
- data/lib/webruby/config.rb +4 -9
- data/lib/webruby/rake/files.rake +2 -2
- data/modules/emscripten/AUTHORS +9 -1
- data/modules/emscripten/CONTRIBUTING.markdown +5 -0
- data/modules/emscripten/ChangeLog +435 -0
- data/modules/emscripten/cmake/Modules/FindOpenAL.cmake +26 -0
- data/modules/emscripten/cmake/Platform/Emscripten.cmake +9 -2
- data/modules/emscripten/em++ +0 -2
- data/modules/emscripten/emcc +92 -32
- data/modules/emscripten/emlink.py +16 -13
- data/modules/emscripten/emmake +1 -1
- data/modules/emscripten/emrun +918 -0
- data/modules/emscripten/emrun.bat +2 -0
- data/modules/emscripten/emscripten.py +545 -20
- data/modules/emscripten/src/analyzer.js +6 -1
- data/modules/emscripten/src/compiler.js +25 -16
- data/modules/emscripten/src/emrun_postjs.js +20 -0
- data/modules/emscripten/{tests → src}/hello_world.js +0 -0
- data/modules/emscripten/src/intertyper.js +45 -16
- data/modules/emscripten/src/jsifier.js +78 -48
- data/modules/emscripten/src/library.js +381 -96
- data/modules/emscripten/src/library_browser.js +50 -53
- data/modules/emscripten/src/library_egl.js +66 -24
- data/modules/emscripten/src/library_fs.js +122 -90
- data/modules/emscripten/src/library_gl.js +739 -353
- data/modules/emscripten/src/library_glfw.js +9 -3
- data/modules/emscripten/src/library_glut.js +10 -5
- data/modules/emscripten/src/library_idbfs.js +14 -14
- data/modules/emscripten/src/library_memfs.js +65 -41
- data/modules/emscripten/src/library_nodefs.js +61 -9
- data/modules/emscripten/src/library_openal.js +4 -4
- data/modules/emscripten/src/library_path.js +9 -13
- data/modules/emscripten/src/library_sdl.js +301 -64
- data/modules/emscripten/src/library_sockfs.js +7 -5
- data/modules/emscripten/src/modules.js +62 -22
- data/modules/emscripten/src/parseTools.js +135 -102
- data/modules/emscripten/src/postamble.js +3 -4
- data/modules/emscripten/src/preamble.js +49 -29
- data/modules/emscripten/src/proxyClient.js +1 -1
- data/modules/emscripten/src/proxyWorker.js +10 -10
- data/modules/emscripten/src/relooper/Relooper.cpp +15 -4
- data/modules/emscripten/src/runtime.js +32 -8
- data/modules/emscripten/src/settings.js +25 -8
- data/modules/emscripten/src/shell.html +6 -3
- data/modules/emscripten/src/shell.js +13 -11
- data/modules/emscripten/src/simd.js +602 -432
- data/modules/emscripten/src/struct_info.json +22 -2
- data/modules/emscripten/src/utility.js +32 -17
- data/modules/emscripten/system/include/SDL/SDL_events.h +1 -0
- data/modules/emscripten/system/include/compat/ctype.h +17 -0
- data/modules/emscripten/system/include/compat/wchar.h +23 -0
- data/modules/emscripten/system/include/compat/wctype.h +23 -0
- data/modules/emscripten/system/include/emscripten/emmintrin.h +87 -0
- data/modules/emscripten/system/include/emscripten/emscripten.h +30 -4
- data/modules/emscripten/system/include/emscripten/vector.h +29 -1
- data/modules/emscripten/system/include/emscripten/xmmintrin.h +131 -0
- data/modules/emscripten/system/include/libcxx/CREDITS.TXT +9 -1
- data/modules/emscripten/system/include/libcxx/__bit_reference +8 -8
- data/modules/emscripten/system/include/libcxx/__config +95 -17
- data/modules/emscripten/system/include/libcxx/__debug +25 -4
- data/modules/emscripten/system/include/libcxx/__functional_03 +7 -7
- data/modules/emscripten/system/include/libcxx/__functional_base +169 -9
- data/modules/emscripten/system/include/libcxx/__functional_base_03 +1 -1
- data/modules/emscripten/system/include/libcxx/__hash_table +25 -25
- data/modules/emscripten/system/include/libcxx/__locale +21 -19
- data/modules/emscripten/system/include/libcxx/__mutex_base +2 -33
- data/modules/emscripten/system/include/libcxx/__split_buffer +9 -9
- data/modules/emscripten/system/include/libcxx/__std_stream +14 -0
- data/modules/emscripten/system/include/libcxx/__tree +35 -26
- data/modules/emscripten/system/include/libcxx/__tuple +15 -15
- data/modules/emscripten/system/include/libcxx/__tuple_03 +2 -2
- data/modules/emscripten/system/include/libcxx/__undef_min_max +8 -0
- data/modules/emscripten/system/include/libcxx/algorithm +121 -110
- data/modules/emscripten/system/include/libcxx/array +15 -15
- data/modules/emscripten/system/include/libcxx/bitset +4 -4
- data/modules/emscripten/system/include/libcxx/chrono +51 -17
- data/modules/emscripten/system/include/libcxx/cmath +25 -23
- data/modules/emscripten/system/include/libcxx/codecvt +21 -18
- data/modules/emscripten/system/include/libcxx/complex +48 -7
- data/modules/emscripten/system/include/libcxx/cstddef +1 -1
- data/modules/emscripten/system/include/libcxx/cstdio +8 -1
- data/modules/emscripten/system/include/libcxx/cstdlib +1 -1
- data/modules/emscripten/system/include/libcxx/cwchar +1 -1
- data/modules/emscripten/system/include/libcxx/deque +26 -12
- data/modules/emscripten/system/include/libcxx/dynarray +311 -0
- data/modules/emscripten/system/include/libcxx/exception +4 -4
- data/modules/emscripten/system/include/libcxx/ext/__hash +3 -3
- data/modules/emscripten/system/include/libcxx/ext/hash_map +19 -15
- data/modules/emscripten/system/include/libcxx/ext/hash_set +7 -3
- data/modules/emscripten/system/include/libcxx/forward_list +33 -7
- data/modules/emscripten/system/include/libcxx/fstream +4 -4
- data/modules/emscripten/system/include/libcxx/functional +200 -170
- data/modules/emscripten/system/include/libcxx/future +83 -39
- data/modules/emscripten/system/include/libcxx/initializer_list +24 -11
- data/modules/emscripten/system/include/libcxx/iomanip +147 -0
- data/modules/emscripten/system/include/libcxx/ios +24 -16
- data/modules/emscripten/system/include/libcxx/iosfwd +19 -19
- data/modules/emscripten/system/include/libcxx/istream +13 -8
- data/modules/emscripten/system/include/libcxx/iterator +108 -417
- data/modules/emscripten/system/include/libcxx/limits +8 -4
- data/modules/emscripten/system/include/libcxx/list +28 -8
- data/modules/emscripten/system/include/libcxx/locale +153 -390
- data/modules/emscripten/system/include/libcxx/map +280 -100
- data/modules/emscripten/system/include/libcxx/memory +49 -97
- data/modules/emscripten/system/include/libcxx/mutex +2 -2
- data/modules/emscripten/system/include/libcxx/new +43 -14
- data/modules/emscripten/system/include/libcxx/numeric +2 -2
- data/modules/emscripten/system/include/libcxx/optional +697 -0
- data/modules/emscripten/system/include/libcxx/ostream +17 -8
- data/modules/emscripten/system/include/libcxx/queue +5 -5
- data/modules/emscripten/system/include/libcxx/random +53 -51
- data/modules/emscripten/system/include/libcxx/ratio +11 -11
- data/modules/emscripten/system/include/libcxx/readme.txt +1 -1
- data/modules/emscripten/system/include/libcxx/regex +23 -20
- data/modules/emscripten/system/include/libcxx/scoped_allocator +1 -1
- data/modules/emscripten/system/include/libcxx/set +166 -2
- data/modules/emscripten/system/include/libcxx/shared_mutex +419 -0
- data/modules/emscripten/system/include/libcxx/sstream +4 -4
- data/modules/emscripten/system/include/libcxx/stack +3 -3
- data/modules/emscripten/system/include/libcxx/streambuf +5 -5
- data/modules/emscripten/system/include/libcxx/string +372 -324
- data/modules/emscripten/system/include/libcxx/support/ibm/limits.h +99 -0
- data/modules/emscripten/system/include/libcxx/support/ibm/support.h +54 -0
- data/modules/emscripten/system/include/libcxx/support/ibm/xlocale.h +326 -0
- data/modules/emscripten/system/include/libcxx/support/win32/limits_win32.h +6 -6
- data/modules/emscripten/system/include/libcxx/support/win32/locale_win32.h +15 -15
- data/modules/emscripten/system/include/libcxx/support/win32/math_win32.h +2 -0
- data/modules/emscripten/system/include/libcxx/support/win32/support.h +6 -1
- data/modules/emscripten/system/include/libcxx/system_error +14 -8
- data/modules/emscripten/system/include/libcxx/thread +7 -8
- data/modules/emscripten/system/include/libcxx/tuple +29 -88
- data/modules/emscripten/system/include/libcxx/type_traits +253 -209
- data/modules/emscripten/system/include/libcxx/typeindex +3 -3
- data/modules/emscripten/system/include/libcxx/unordered_map +162 -101
- data/modules/emscripten/system/include/libcxx/unordered_set +79 -2
- data/modules/emscripten/system/include/libcxx/utility +20 -20
- data/modules/emscripten/system/include/libcxx/valarray +23 -23
- data/modules/emscripten/system/include/libcxx/vector +114 -91
- data/modules/emscripten/system/lib/libc/musl/src/regex/regcomp.c +3352 -0
- data/modules/emscripten/system/lib/libc/musl/src/regex/regerror.c +35 -0
- data/modules/emscripten/system/lib/libc/musl/src/regex/regexec.c +1011 -0
- data/modules/emscripten/system/lib/libc/musl/src/regex/tre-mem.c +158 -0
- data/modules/emscripten/system/lib/libc/musl/src/regex/tre.h +231 -0
- data/modules/emscripten/system/lib/libcextra.symbols +7 -0
- data/modules/emscripten/system/lib/libcxx/CREDITS.TXT +9 -1
- data/modules/emscripten/system/lib/libcxx/algorithm.cpp +1 -0
- data/modules/emscripten/system/lib/libcxx/debug.cpp +66 -42
- data/modules/emscripten/system/lib/libcxx/exception.cpp +88 -16
- data/modules/emscripten/system/lib/libcxx/future.cpp +6 -0
- data/modules/emscripten/system/lib/libcxx/ios.cpp +7 -2
- data/modules/emscripten/system/lib/libcxx/iostream.cpp +8 -8
- data/modules/emscripten/system/lib/libcxx/locale.cpp +38 -11
- data/modules/emscripten/system/lib/libcxx/mutex.cpp +3 -0
- data/modules/emscripten/system/lib/libcxx/new.cpp +44 -10
- data/modules/emscripten/system/lib/libcxx/optional.cpp +25 -0
- data/modules/emscripten/system/lib/libcxx/random.cpp +26 -0
- data/modules/emscripten/system/lib/libcxx/readme.txt +1 -1
- data/modules/emscripten/system/lib/libcxx/shared_mutex.cpp +101 -0
- data/modules/emscripten/system/lib/libcxx/stdexcept.cpp +11 -7
- data/modules/emscripten/system/lib/libcxx/string.cpp +3 -1
- data/modules/emscripten/system/lib/libcxx/strstream.cpp +7 -7
- data/modules/emscripten/system/lib/libcxx/support/win32/locale_win32.cpp +12 -13
- data/modules/emscripten/system/lib/libcxx/support/win32/support.cpp +33 -36
- data/modules/emscripten/system/lib/libcxx/symbols +187 -168
- data/modules/emscripten/system/lib/libcxx/system_error.cpp +1 -0
- data/modules/emscripten/system/lib/libcxx/thread.cpp +7 -3
- data/modules/emscripten/system/lib/libcxx/typeinfo.cpp +9 -6
- data/modules/emscripten/system/lib/libcxx/valarray.cpp +2 -0
- data/modules/emscripten/third_party/lzma.js/doit.bat +4 -0
- data/modules/emscripten/third_party/lzma.js/doit.sh +9 -2
- data/modules/emscripten/tools/cache.py +5 -7
- data/modules/emscripten/tools/cache.pyc +0 -0
- data/modules/emscripten/tools/eliminator/asm-eliminator-test-output.js +7 -0
- data/modules/emscripten/tools/eliminator/asm-eliminator-test.js +9 -1
- data/modules/emscripten/tools/eliminator/eliminator-test-output.js +3 -0
- data/modules/emscripten/tools/eliminator/eliminator-test.js +9 -1
- data/modules/emscripten/tools/file_packager.py +93 -50
- data/modules/emscripten/tools/js-optimizer.js +98 -48
- data/modules/emscripten/tools/js_optimizer.py +4 -4
- data/modules/emscripten/tools/js_optimizer.pyc +0 -0
- data/modules/emscripten/tools/jsrun.py +1 -1
- data/modules/emscripten/tools/jsrun.pyc +0 -0
- data/modules/emscripten/tools/response_file.py +6 -0
- data/modules/emscripten/tools/response_file.pyc +0 -0
- data/modules/emscripten/tools/settings_template_readonly.py +2 -0
- data/modules/emscripten/tools/shared.py +88 -34
- data/modules/emscripten/tools/shared.pyc +0 -0
- data/modules/emscripten/tools/split.py +21 -13
- data/modules/mruby/build_config.rb +7 -1
- data/modules/mruby/doc/compile/README.md +5 -9
- data/modules/mruby/include/mrbconf.h +5 -2
- data/modules/mruby/include/mruby/array.h +1 -0
- data/modules/mruby/include/mruby/compile.h +2 -4
- data/modules/mruby/include/mruby/dump.h +7 -16
- data/modules/mruby/include/mruby/hash.h +1 -1
- data/modules/mruby/include/mruby/irep.h +14 -2
- data/modules/mruby/include/mruby/khash.h +8 -7
- data/modules/mruby/include/mruby/string.h +1 -0
- data/modules/mruby/include/mruby/value.h +5 -2
- data/modules/mruby/include/mruby.h +12 -13
- data/modules/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +16 -6
- data/modules/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +18 -30
- data/modules/mruby/mrbgems/mruby-fiber/src/fiber.c +21 -0
- data/modules/mruby/mrbgems/mruby-math/src/math.c +1 -1
- data/modules/mruby/mrbgems/mruby-random/src/random.c +144 -47
- data/modules/mruby/mrbgems/mruby-random/test/random.rb +44 -0
- data/modules/mruby/mrbgems/mruby-struct/src/struct.c +5 -5
- data/modules/mruby/mrblib/numeric.rb +99 -33
- data/modules/mruby/src/array.c +11 -4
- data/modules/mruby/src/backtrace.c +2 -2
- data/modules/mruby/src/class.c +49 -30
- data/modules/mruby/src/codegen.c +131 -79
- data/modules/mruby/src/debug.c +1 -1
- data/modules/mruby/src/dump.c +213 -163
- data/modules/mruby/src/error.c +17 -17
- data/modules/mruby/src/error.h +1 -1
- data/modules/mruby/src/etc.c +10 -0
- data/modules/mruby/src/gc.c +35 -17
- data/modules/mruby/src/hash.c +5 -5
- data/modules/mruby/src/kernel.c +36 -14
- data/modules/mruby/src/load.c +238 -296
- data/modules/mruby/src/numeric.c +18 -98
- data/modules/mruby/src/object.c +3 -5
- data/modules/mruby/src/parse.y +63 -56
- data/modules/mruby/src/proc.c +8 -5
- data/modules/mruby/src/re.h +0 -1
- data/modules/mruby/src/state.c +65 -27
- data/modules/mruby/src/string.c +3 -31
- data/modules/mruby/src/symbol.c +3 -3
- data/modules/mruby/src/variable.c +12 -5
- data/modules/mruby/src/vm.c +90 -72
- data/modules/mruby/tasks/mruby_build.rake +10 -1
- data/modules/mruby/tasks/toolchains/gcc.rake +12 -2
- data/modules/mruby/tasks/toolchains/{vs2012.rake → visualcpp.rake} +1 -1
- data/modules/mruby/test/driver.c +3 -3
- data/modules/mruby/test/t/array.rb +5 -5
- data/modules/mruby/test/t/class.rb +14 -1
- data/modules/mruby/test/t/kernel.rb +4 -0
- data/modules/mruby/test/t/module.rb +4 -4
- data/modules/mruby/test/t/nameerror.rb +1 -1
- data/modules/mruby/tools/mrbc/mrbc.c +23 -17
- data/modules/mruby/travis_config.rb +10 -1
- metadata +28 -5
- data/modules/mruby/tasks/toolchains/vs2010.rake +0 -3
@@ -9,8 +9,9 @@ header files (so that the JS compiler can see the constants in those
|
|
9
9
|
headers, for the libc implementation in JS).
|
10
10
|
'''
|
11
11
|
|
12
|
-
import os, sys, json, optparse, subprocess, re, time, multiprocessing, string, logging
|
12
|
+
import os, sys, json, optparse, subprocess, re, time, multiprocessing, string, logging, shutil
|
13
13
|
|
14
|
+
from tools import shared
|
14
15
|
from tools import jsrun, cache as cache_module, tempfiles
|
15
16
|
from tools.response_file import read_response_file
|
16
17
|
|
@@ -25,7 +26,6 @@ def get_configuration():
|
|
25
26
|
if hasattr(get_configuration, 'configuration'):
|
26
27
|
return get_configuration.configuration
|
27
28
|
|
28
|
-
from tools import shared
|
29
29
|
configuration = shared.Configuration(environ=os.environ)
|
30
30
|
get_configuration.configuration = configuration
|
31
31
|
return configuration
|
@@ -117,7 +117,7 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
|
|
117
117
|
last = func_start
|
118
118
|
func_start = ll.find('\ndefine ', func_start)
|
119
119
|
if func_start > last:
|
120
|
-
pre.append(ll[last:min(func_start+1, meta_start)] + '\n')
|
120
|
+
pre.append(ll[last:min(func_start+1, meta_start) if meta_start > 0 else func_start+1] + '\n')
|
121
121
|
if func_start < 0:
|
122
122
|
pre.append(ll[last:meta_start] + '\n')
|
123
123
|
break
|
@@ -425,8 +425,8 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
|
|
425
425
|
Counter.i += 1
|
426
426
|
bad = 'b' + str(i)
|
427
427
|
params = ','.join(['p%d' % p for p in range(len(sig)-1)])
|
428
|
-
coercions = ';'.join(['p%d = %
|
429
|
-
ret = '' if sig[0] == 'v' else ('return %
|
428
|
+
coercions = ';'.join(['p%d = %s' % (p, shared.JS.make_coercion('p%d' % p, sig[p+1], settings)) for p in range(len(sig)-1)]) + ';'
|
429
|
+
ret = '' if sig[0] == 'v' else ('return %s' % shared.JS.make_initializer(sig[0], settings))
|
430
430
|
start = raw.index('[')
|
431
431
|
end = raw.rindex(']')
|
432
432
|
body = raw[start+1:end].split(',')
|
@@ -451,7 +451,7 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
|
|
451
451
|
math_envs = ['Math.min'] # TODO: move min to maths
|
452
452
|
asm_setup += '\n'.join(['var %s = %s;' % (f.replace('.', '_'), f) for f in math_envs])
|
453
453
|
|
454
|
-
if settings['
|
454
|
+
if settings['PRECISE_F32']: maths += ['Math.fround']
|
455
455
|
|
456
456
|
basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat'] + [m.replace('.', '_') for m in math_envs]
|
457
457
|
if settings['RESERVED_FUNCTION_POINTERS'] > 0: basic_funcs.append('jsCall')
|
@@ -476,18 +476,14 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
|
|
476
476
|
|
477
477
|
asm_runtime_funcs = ['stackAlloc', 'stackSave', 'stackRestore', 'setThrew'] + ['setTempRet%d' % i for i in range(10)]
|
478
478
|
# function tables
|
479
|
-
def asm_coerce(value, sig):
|
480
|
-
if sig == 'v': return value
|
481
|
-
return ('+' if sig != 'i' else '') + value + ('|0' if sig == 'i' else '')
|
482
|
-
|
483
479
|
function_tables = ['dynCall_' + table for table in last_forwarded_json['Functions']['tables']]
|
484
480
|
function_tables_impls = []
|
485
481
|
|
486
482
|
for sig in last_forwarded_json['Functions']['tables'].iterkeys():
|
487
483
|
args = ','.join(['a' + str(i) for i in range(1, len(sig))])
|
488
|
-
arg_coercions = ' '.join(['a' + str(i) + '=' +
|
489
|
-
coerced_args = ','.join([
|
490
|
-
ret = ('return ' if sig[0] != 'v' else '') +
|
484
|
+
arg_coercions = ' '.join(['a' + str(i) + '=' + shared.JS.make_coercion('a' + str(i), sig[i], settings) + ';' for i in range(1, len(sig))])
|
485
|
+
coerced_args = ','.join([shared.JS.make_coercion('a' + str(i), sig[i], settings) for i in range(1, len(sig))])
|
486
|
+
ret = ('return ' if sig[0] != 'v' else '') + shared.JS.make_coercion('FUNCTION_TABLE_%s[index&{{{ FTM_%s }}}](%s)' % (sig, sig, coerced_args), sig[0], settings)
|
491
487
|
function_tables_impls.append('''
|
492
488
|
function dynCall_%s(index%s%s) {
|
493
489
|
index = index|0;
|
@@ -497,7 +493,7 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
|
|
497
493
|
''' % (sig, ',' if len(sig) > 1 else '', args, arg_coercions, ret))
|
498
494
|
|
499
495
|
for i in range(settings['RESERVED_FUNCTION_POINTERS']):
|
500
|
-
jsret = ('return ' if sig[0] != 'v' else '') +
|
496
|
+
jsret = ('return ' if sig[0] != 'v' else '') + shared.JS.make_coercion('jsCall(%d%s%s)' % (i, ',' if coerced_args else '', coerced_args), sig[0], settings)
|
501
497
|
function_tables_impls.append('''
|
502
498
|
function jsCall_%s_%s(%s) {
|
503
499
|
%s
|
@@ -505,7 +501,6 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
|
|
505
501
|
}
|
506
502
|
|
507
503
|
''' % (sig, i, args, arg_coercions, jsret))
|
508
|
-
from tools import shared
|
509
504
|
shared.Settings.copy(settings)
|
510
505
|
asm_setup += '\n' + shared.JS.make_invoke(sig) + '\n'
|
511
506
|
basic_funcs.append('invoke_%s' % sig)
|
@@ -578,14 +573,14 @@ var asm = (function(global, env, buffer) {
|
|
578
573
|
var HEAPU32 = new global.Uint32Array(buffer);
|
579
574
|
var HEAPF32 = new global.Float32Array(buffer);
|
580
575
|
var HEAPF64 = new global.Float64Array(buffer);
|
581
|
-
''' % (asm_setup, "'use asm';" if not forwarded_json['Types']['hasInlineJS'] and not settings['SIDE_MODULE'] else "'almost asm';") + '\n' + asm_global_vars + '''
|
576
|
+
''' % (asm_setup, "'use asm';" if not forwarded_json['Types']['hasInlineJS'] and not settings['SIDE_MODULE'] and settings['ASM_JS'] == 1 else "'almost asm';") + '\n' + asm_global_vars + '''
|
582
577
|
var __THREW__ = 0;
|
583
578
|
var threwValue = 0;
|
584
579
|
var setjmpId = 0;
|
585
580
|
var undef = 0;
|
586
581
|
var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
|
587
582
|
''' + ''.join(['''
|
588
|
-
var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs + '''
|
583
|
+
var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs] + [' var tempFloat = %s;\n' % ('Math_fround(0)' if settings.get('PRECISE_F32') else '0.0')] + ['''
|
589
584
|
// EMSCRIPTEN_START_FUNCS
|
590
585
|
function stackAlloc(size) {
|
591
586
|
size = size|0;
|
@@ -711,6 +706,539 @@ Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
|
|
711
706
|
|
712
707
|
outfile.close()
|
713
708
|
|
709
|
+
# emscript_fast: emscript'en code using the 'fast' compilation path, using
|
710
|
+
# an LLVM backend
|
711
|
+
# FIXME: this is just a copy-paste of normal emscript(), and we trample it
|
712
|
+
# if the proper env var is set (see below). we should refactor to
|
713
|
+
# share code between the two, once emscript_fast stabilizes (or,
|
714
|
+
# leaving it separate like it is will make it trivial to rip out
|
715
|
+
# if the experiment fails)
|
716
|
+
|
717
|
+
def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
|
718
|
+
jcache=None, temp_files=None, DEBUG=None, DEBUG_CACHE=None):
|
719
|
+
"""Runs the emscripten LLVM-to-JS compiler. We parallelize as much as possible
|
720
|
+
|
721
|
+
Args:
|
722
|
+
infile: The path to the input LLVM assembly file.
|
723
|
+
settings: JSON-formatted settings that override the values
|
724
|
+
defined in src/settings.js.
|
725
|
+
outfile: The file where the output is written.
|
726
|
+
"""
|
727
|
+
|
728
|
+
assert(settings['ASM_JS']) # TODO: apply ASM_JS even in -O0 for fastcomp
|
729
|
+
|
730
|
+
# Overview:
|
731
|
+
# * Run LLVM backend to emit JS. JS includes function bodies, memory initializer,
|
732
|
+
# and various metadata
|
733
|
+
# * Run compiler.js on the metadata to emit the shell js code, pre/post-ambles,
|
734
|
+
# JS library dependencies, etc.
|
735
|
+
|
736
|
+
if DEBUG: logging.debug('emscript: llvm backend')
|
737
|
+
|
738
|
+
# TODO: proper temp files
|
739
|
+
# TODO: use a single LLVM toolchain instead of normal for source, pnacl for simplification, custom for js backend
|
740
|
+
|
741
|
+
if DEBUG: shutil.copyfile(infile, os.path.join(shared.CANONICAL_TEMP_DIR, 'temp0.ll'))
|
742
|
+
|
743
|
+
extra_opt_args = []
|
744
|
+
#if DEBUG: extra_opt_args.append('-time-passes')
|
745
|
+
|
746
|
+
if DEBUG: t = time.time()
|
747
|
+
|
748
|
+
if DEBUG: logging.debug(' ..1..')
|
749
|
+
temp1 = temp_files.get('.1.bc').name
|
750
|
+
shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'opt'), infile, '-pnacl-abi-simplify-preopt', '-o', temp1] + extra_opt_args))
|
751
|
+
assert os.path.exists(temp1)
|
752
|
+
if DEBUG:
|
753
|
+
shutil.copyfile(temp1, os.path.join(shared.CANONICAL_TEMP_DIR, 'temp1.bc'))
|
754
|
+
shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'llvm-dis'), 'temp1.bc', '-o', 'temp1.ll']))
|
755
|
+
|
756
|
+
#if DEBUG: logging.debug(' ..2..')
|
757
|
+
#temp2 = temp_files.get('.2.bc').name
|
758
|
+
#shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'opt'), temp1, '-O3', '-o', temp2]))
|
759
|
+
#assert os.path.exists(temp2)
|
760
|
+
#if DEBUG:
|
761
|
+
# shutil.copyfile(temp2, os.path.join(shared.CANONICAL_TEMP_DIR, 'temp2.bc'))
|
762
|
+
# shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'llvm-dis'), 'temp2.bc', '-o', 'temp2.ll']))
|
763
|
+
temp2 = temp1 # XXX if we optimize the bc, we remove some pnacl clutter, but it also makes varargs stores be 8-byte aligned
|
764
|
+
|
765
|
+
if DEBUG: logging.debug(' ..3..')
|
766
|
+
temp3 = temp_files.get('.3.bc').name
|
767
|
+
shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'opt'), temp2, '-pnacl-abi-simplify-postopt', '-o', temp3] + extra_opt_args))
|
768
|
+
#'-print-after-all'
|
769
|
+
assert os.path.exists(temp3)
|
770
|
+
if DEBUG:
|
771
|
+
shutil.copyfile(temp3, os.path.join(shared.CANONICAL_TEMP_DIR, 'temp3.bc'))
|
772
|
+
shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'llvm-dis'), 'temp3.bc', '-o', 'temp3.ll']))
|
773
|
+
|
774
|
+
if DEBUG:
|
775
|
+
logging.debug(' emscript: ir simplification took %s seconds' % (time.time() - t))
|
776
|
+
t = time.time()
|
777
|
+
|
778
|
+
if DEBUG: logging.debug(' ..4..')
|
779
|
+
temp4 = temp_files.get('.4.js').name
|
780
|
+
backend_compiler = os.path.join(shared.LLVM_ROOT, 'llc')
|
781
|
+
shared.jsrun.timeout_run(subprocess.Popen([backend_compiler, temp3, '-march=js', '-filetype=asm', '-o', temp4], stdout=subprocess.PIPE))
|
782
|
+
if DEBUG: shutil.copyfile(temp4, os.path.join(shared.CANONICAL_TEMP_DIR, 'temp4.js'))
|
783
|
+
|
784
|
+
if DEBUG:
|
785
|
+
logging.debug(' emscript: llvm backend took %s seconds' % (time.time() - t))
|
786
|
+
t = time.time()
|
787
|
+
|
788
|
+
# Split up output
|
789
|
+
backend_output = open(temp4).read()
|
790
|
+
#if DEBUG: print >> sys.stderr, backend_output
|
791
|
+
|
792
|
+
start_funcs_marker = '// EMSCRIPTEN_START_FUNCTIONS'
|
793
|
+
end_funcs_marker = '// EMSCRIPTEN_END_FUNCTIONS'
|
794
|
+
metadata_split_marker = '// EMSCRIPTEN_METADATA'
|
795
|
+
|
796
|
+
start_funcs = backend_output.index(start_funcs_marker)
|
797
|
+
end_funcs = backend_output.rindex(end_funcs_marker)
|
798
|
+
metadata_split = backend_output.rindex(metadata_split_marker)
|
799
|
+
|
800
|
+
funcs = backend_output[start_funcs+len(start_funcs_marker):end_funcs]
|
801
|
+
metadata_raw = backend_output[metadata_split+len(metadata_split_marker):]
|
802
|
+
#if DEBUG: print >> sys.stderr, "METAraw", metadata_raw
|
803
|
+
metadata = json.loads(metadata_raw)
|
804
|
+
mem_init = backend_output[end_funcs+len(end_funcs_marker):metadata_split]
|
805
|
+
#if DEBUG: print >> sys.stderr, "FUNCS", funcs
|
806
|
+
#if DEBUG: print >> sys.stderr, "META", metadata
|
807
|
+
#if DEBUG: print >> sys.stderr, "meminit", mem_init
|
808
|
+
|
809
|
+
# function table masks
|
810
|
+
|
811
|
+
table_sizes = {}
|
812
|
+
for k, v in metadata['tables'].iteritems():
|
813
|
+
table_sizes[k] = str(v.count(',')) # undercounts by one, but that is what we want
|
814
|
+
funcs = re.sub(r"#FM_(\w+)#", lambda m: table_sizes[m.groups(0)[0]], funcs)
|
815
|
+
|
816
|
+
# fix +float into float.0, if not running js opts
|
817
|
+
if not settings['RUNNING_JS_OPTS']:
|
818
|
+
def fix_dot_zero(m):
|
819
|
+
num = m.group(3)
|
820
|
+
# TODO: handle 0x floats?
|
821
|
+
if num.find('.') < 0:
|
822
|
+
e = num.find('e');
|
823
|
+
if e < 0:
|
824
|
+
num += '.0'
|
825
|
+
else:
|
826
|
+
num = num[:e] + '.0' + num[e:]
|
827
|
+
return m.group(1) + m.group(2) + num
|
828
|
+
funcs = re.sub(r'([(=,+\-*/%] *)\+(-?)((0x)?[0-9a-f]*\.?[0-9]+([eE][-+]?[0-9]+)?)', lambda m: fix_dot_zero(m), funcs)
|
829
|
+
|
830
|
+
# js compiler
|
831
|
+
|
832
|
+
if DEBUG: logging.debug('emscript: js compiler glue')
|
833
|
+
|
834
|
+
# Settings changes
|
835
|
+
assert settings['TARGET_LE32'] == 1
|
836
|
+
settings['TARGET_LE32'] = 2
|
837
|
+
if 'i64Add' in metadata['declares']: # TODO: others, once we split them up
|
838
|
+
settings['PRECISE_I64_MATH'] = 2
|
839
|
+
metadata['declares'] = filter(lambda i64_func: i64_func not in ['getHigh32', 'setHigh32', '__muldi3', '__divdi3', '__remdi3', '__udivdi3', '__uremdi3'], metadata['declares']) # FIXME: do these one by one as normal js lib funcs
|
840
|
+
|
841
|
+
# Integrate info from backend
|
842
|
+
settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE'] = list(
|
843
|
+
set(settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE'] + map(shared.JS.to_nice_ident, metadata['declares'])).difference(
|
844
|
+
map(lambda x: x[1:], metadata['implementedFunctions'])
|
845
|
+
)
|
846
|
+
) + map(lambda x: x[1:], metadata['externs'])
|
847
|
+
|
848
|
+
# Save settings to a file to work around v8 issue 1579
|
849
|
+
settings_file = temp_files.get('.txt').name
|
850
|
+
def save_settings():
|
851
|
+
global settings_text
|
852
|
+
settings_text = json.dumps(settings, sort_keys=True)
|
853
|
+
s = open(settings_file, 'w')
|
854
|
+
s.write(settings_text)
|
855
|
+
s.close()
|
856
|
+
save_settings()
|
857
|
+
|
858
|
+
# Call js compiler
|
859
|
+
if DEBUG: t = time.time()
|
860
|
+
out = jsrun.run_js(path_from_root('src', 'compiler.js'), compiler_engine, [settings_file, ';', 'glue'] + libraries, stdout=subprocess.PIPE, stderr=STDERR_FILE,
|
861
|
+
cwd=path_from_root('src'))
|
862
|
+
assert '//FORWARDED_DATA:' in out, 'Did not receive forwarded data in pre output - process failed?'
|
863
|
+
glue, forwarded_data = out.split('//FORWARDED_DATA:')
|
864
|
+
|
865
|
+
if DEBUG:
|
866
|
+
logging.debug(' emscript: glue took %s seconds' % (time.time() - t))
|
867
|
+
t = time.time()
|
868
|
+
|
869
|
+
last_forwarded_json = forwarded_json = json.loads(forwarded_data)
|
870
|
+
|
871
|
+
# merge in information from llvm backend
|
872
|
+
|
873
|
+
last_forwarded_json['Functions']['tables'] = metadata['tables']
|
874
|
+
|
875
|
+
'''indexed_functions = set()
|
876
|
+
for key in forwarded_json['Functions']['indexedFunctions'].iterkeys():
|
877
|
+
indexed_functions.add(key)'''
|
878
|
+
|
879
|
+
pre, post = glue.split('// EMSCRIPTEN_END_FUNCS')
|
880
|
+
|
881
|
+
#print >> sys.stderr, 'glue:', pre, '\n\n||||||||||||||||\n\n', post, '...............'
|
882
|
+
|
883
|
+
# memory and global initializers
|
884
|
+
|
885
|
+
global_initializers = ', '.join(map(lambda i: '{ func: function() { %s() } }' % i, metadata['initializers']))
|
886
|
+
|
887
|
+
pre = pre.replace('STATICTOP = STATIC_BASE + 0;', '''STATICTOP = STATIC_BASE + Runtime.alignMemory(%d);
|
888
|
+
/* global initializers */ __ATINIT__.push(%s);
|
889
|
+
%s''' % (mem_init.count(',')+1, global_initializers, mem_init)) # XXX wrong size calculation!
|
890
|
+
|
891
|
+
funcs_js = [funcs]
|
892
|
+
if settings.get('ASM_JS'):
|
893
|
+
parts = pre.split('// ASM_LIBRARY FUNCTIONS\n')
|
894
|
+
if len(parts) > 1:
|
895
|
+
pre = parts[0]
|
896
|
+
funcs_js.append(parts[1])
|
897
|
+
|
898
|
+
# calculations on merged forwarded data TODO
|
899
|
+
|
900
|
+
# merge forwarded data
|
901
|
+
assert settings.get('ASM_JS'), 'fastcomp is asm.js only'
|
902
|
+
settings['EXPORTED_FUNCTIONS'] = forwarded_json['EXPORTED_FUNCTIONS']
|
903
|
+
all_exported_functions = set(settings['EXPORTED_FUNCTIONS']) # both asm.js and otherwise
|
904
|
+
for additional_export in settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE']: # additional functions to export from asm, if they are implemented
|
905
|
+
all_exported_functions.add('_' + additional_export)
|
906
|
+
exported_implemented_functions = set()
|
907
|
+
export_bindings = settings['EXPORT_BINDINGS']
|
908
|
+
export_all = settings['EXPORT_ALL']
|
909
|
+
for key in metadata['implementedFunctions'] + forwarded_json['Functions']['implementedFunctions'].keys(): # XXX perf
|
910
|
+
if key in all_exported_functions or export_all or (export_bindings and key.startswith('_emscripten_bind')):
|
911
|
+
exported_implemented_functions.add(key)
|
912
|
+
|
913
|
+
#if DEBUG: outfile.write('// pre\n')
|
914
|
+
outfile.write(pre)
|
915
|
+
pre = None
|
916
|
+
|
917
|
+
#if DEBUG: outfile.write('// funcs\n')
|
918
|
+
|
919
|
+
if settings.get('ASM_JS'):
|
920
|
+
# Move preAsms to their right place
|
921
|
+
def move_preasm(m):
|
922
|
+
contents = m.groups(0)[0]
|
923
|
+
outfile.write(contents + '\n')
|
924
|
+
return ''
|
925
|
+
funcs_js[1] = re.sub(r'/\* PRE_ASM \*/(.*)\n', lambda m: move_preasm(m), funcs_js[1])
|
926
|
+
|
927
|
+
funcs_js += ['\n// EMSCRIPTEN_END_FUNCS\n']
|
928
|
+
|
929
|
+
simple = os.environ.get('EMCC_SIMPLE_ASM')
|
930
|
+
class Counter:
|
931
|
+
i = 0
|
932
|
+
j = 0
|
933
|
+
if 'pre' in last_forwarded_json['Functions']['tables']:
|
934
|
+
pre_tables = last_forwarded_json['Functions']['tables']['pre']
|
935
|
+
del last_forwarded_json['Functions']['tables']['pre']
|
936
|
+
else:
|
937
|
+
pre_tables = ''
|
938
|
+
|
939
|
+
def make_table(sig, raw):
|
940
|
+
i = Counter.i
|
941
|
+
Counter.i += 1
|
942
|
+
bad = 'b' + str(i)
|
943
|
+
params = ','.join(['p%d' % p for p in range(len(sig)-1)])
|
944
|
+
coerced_params = ','.join([shared.JS.make_coercion('p%d', sig[p+1], settings) % p for p in range(len(sig)-1)])
|
945
|
+
coercions = ';'.join(['p%d = %s' % (p, shared.JS.make_coercion('p%d' % p, sig[p+1], settings)) for p in range(len(sig)-1)]) + ';'
|
946
|
+
def make_func(name, code):
|
947
|
+
return 'function %s(%s) { %s %s }' % (name, params, coercions, code)
|
948
|
+
Counter.pre = [make_func(bad, ('abort' if not settings['ASSERTIONS'] else 'nullFunc') + '(' + str(i) + ');' + (
|
949
|
+
'' if sig[0] == 'v' else ('return %s' % shared.JS.make_initializer(sig[0], settings))
|
950
|
+
))]
|
951
|
+
start = raw.index('[')
|
952
|
+
end = raw.rindex(']')
|
953
|
+
body = raw[start+1:end].split(',')
|
954
|
+
for j in range(settings['RESERVED_FUNCTION_POINTERS']):
|
955
|
+
body[settings['FUNCTION_POINTER_ALIGNMENT'] * (1 + j)] = 'jsCall_%s_%s' % (sig, j)
|
956
|
+
Counter.j = 0
|
957
|
+
def fix_item(item):
|
958
|
+
Counter.j += 1
|
959
|
+
newline = Counter.j % 30 == 29
|
960
|
+
if item == '0': return bad if not newline else (bad + '\n')
|
961
|
+
if item not in metadata['implementedFunctions']:
|
962
|
+
# this is imported into asm, we must wrap it
|
963
|
+
call_ident = item
|
964
|
+
if call_ident in metadata['redirects']: call_ident = metadata['redirects'][call_ident]
|
965
|
+
if not call_ident.startswith('_') and not call_ident.startswith('Math_'): call_ident = '_' + call_ident
|
966
|
+
code = call_ident + '(' + coerced_params + ')'
|
967
|
+
if sig[0] != 'v':
|
968
|
+
code = 'return ' + shared.JS.make_coercion(code, sig[0], settings)
|
969
|
+
code += ';'
|
970
|
+
Counter.pre.append(make_func(item + '__wrapper', code))
|
971
|
+
return item + '__wrapper'
|
972
|
+
return item if not newline else (item + '\n')
|
973
|
+
body = ','.join(map(fix_item, body))
|
974
|
+
return ('\n'.join(Counter.pre), ''.join([raw[:start+1], body, raw[end:]]))
|
975
|
+
|
976
|
+
infos = [make_table(sig, raw) for sig, raw in last_forwarded_json['Functions']['tables'].iteritems()]
|
977
|
+
Counter.pre = []
|
978
|
+
|
979
|
+
function_tables_defs = '\n'.join([info[0] for info in infos]) + '\n// EMSCRIPTEN_END_FUNCS\n' + '\n'.join([info[1] for info in infos])
|
980
|
+
|
981
|
+
asm_setup = ''
|
982
|
+
maths = ['Math.' + func for func in ['floor', 'abs', 'sqrt', 'pow', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'atan2', 'exp', 'log', 'ceil', 'imul']]
|
983
|
+
fundamentals = ['Math', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint16Array', 'Uint32Array', 'Float32Array', 'Float64Array']
|
984
|
+
math_envs = ['Math.min'] # TODO: move min to maths
|
985
|
+
asm_setup += '\n'.join(['var %s = %s;' % (f.replace('.', '_'), f) for f in math_envs])
|
986
|
+
|
987
|
+
if settings['PRECISE_F32']: maths += ['Math.fround']
|
988
|
+
|
989
|
+
basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat'] + [m.replace('.', '_') for m in math_envs]
|
990
|
+
if settings['RESERVED_FUNCTION_POINTERS'] > 0: basic_funcs.append('jsCall')
|
991
|
+
if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE', 'SAFE_HEAP_CLEAR']
|
992
|
+
if settings['CHECK_HEAP_ALIGN']: basic_funcs += ['CHECK_ALIGN_2', 'CHECK_ALIGN_4', 'CHECK_ALIGN_8']
|
993
|
+
if settings['ASSERTIONS']:
|
994
|
+
basic_funcs += ['nullFunc']
|
995
|
+
asm_setup += 'function nullFunc(x) { Module["printErr"]("Invalid function pointer called. Perhaps a miscast function pointer (check compilation warnings) or bad vtable lookup (maybe due to derefing a bad pointer, like NULL)?"); abort(x) }\n'
|
996
|
+
|
997
|
+
basic_vars = ['STACKTOP', 'STACK_MAX', 'tempDoublePtr', 'ABORT']
|
998
|
+
basic_float_vars = ['NaN', 'Infinity']
|
999
|
+
|
1000
|
+
if metadata.get('preciseI64MathUsed') or \
|
1001
|
+
forwarded_json['Functions']['libraryFunctions'].get('llvm_cttz_i32') or \
|
1002
|
+
forwarded_json['Functions']['libraryFunctions'].get('llvm_ctlz_i32'):
|
1003
|
+
basic_vars += ['cttz_i8', 'ctlz_i8']
|
1004
|
+
|
1005
|
+
if settings.get('DLOPEN_SUPPORT'):
|
1006
|
+
for sig in last_forwarded_json['Functions']['tables'].iterkeys():
|
1007
|
+
basic_vars.append('F_BASE_%s' % sig)
|
1008
|
+
asm_setup += ' var F_BASE_%s = %s;\n' % (sig, 'FUNCTION_TABLE_OFFSET' if settings.get('SIDE_MODULE') else '0') + '\n'
|
1009
|
+
|
1010
|
+
asm_runtime_funcs = ['stackAlloc', 'stackSave', 'stackRestore', 'setThrew'] + ['setTempRet%d' % i for i in range(10)]
|
1011
|
+
# function tables
|
1012
|
+
function_tables = ['dynCall_' + table for table in last_forwarded_json['Functions']['tables']]
|
1013
|
+
function_tables_impls = []
|
1014
|
+
|
1015
|
+
for sig in last_forwarded_json['Functions']['tables'].iterkeys():
|
1016
|
+
args = ','.join(['a' + str(i) for i in range(1, len(sig))])
|
1017
|
+
arg_coercions = ' '.join(['a' + str(i) + '=' + shared.JS.make_coercion('a' + str(i), sig[i], settings) + ';' for i in range(1, len(sig))])
|
1018
|
+
coerced_args = ','.join([shared.JS.make_coercion('a' + str(i), sig[i], settings) for i in range(1, len(sig))])
|
1019
|
+
ret = ('return ' if sig[0] != 'v' else '') + shared.JS.make_coercion('FUNCTION_TABLE_%s[index&{{{ FTM_%s }}}](%s)' % (sig, sig, coerced_args), sig[0], settings)
|
1020
|
+
function_tables_impls.append('''
|
1021
|
+
function dynCall_%s(index%s%s) {
|
1022
|
+
index = index|0;
|
1023
|
+
%s
|
1024
|
+
%s;
|
1025
|
+
}
|
1026
|
+
''' % (sig, ',' if len(sig) > 1 else '', args, arg_coercions, ret))
|
1027
|
+
|
1028
|
+
for i in range(settings['RESERVED_FUNCTION_POINTERS']):
|
1029
|
+
jsret = ('return ' if sig[0] != 'v' else '') + shared.JS.make_coercion('jsCall(%d%s%s)' % (i, ',' if coerced_args else '', coerced_args), sig[0], settings)
|
1030
|
+
function_tables_impls.append('''
|
1031
|
+
function jsCall_%s_%s(%s) {
|
1032
|
+
%s
|
1033
|
+
%s;
|
1034
|
+
}
|
1035
|
+
|
1036
|
+
''' % (sig, i, args, arg_coercions, jsret))
|
1037
|
+
shared.Settings.copy(settings)
|
1038
|
+
asm_setup += '\n' + shared.JS.make_invoke(sig) + '\n'
|
1039
|
+
basic_funcs.append('invoke_%s' % sig)
|
1040
|
+
if settings.get('DLOPEN_SUPPORT'):
|
1041
|
+
asm_setup += '\n' + shared.JS.make_extcall(sig) + '\n'
|
1042
|
+
basic_funcs.append('extCall_%s' % sig)
|
1043
|
+
|
1044
|
+
# calculate exports
|
1045
|
+
exported_implemented_functions = list(exported_implemented_functions) + metadata['initializers']
|
1046
|
+
exported_implemented_functions.append('runPostSets')
|
1047
|
+
exports = []
|
1048
|
+
if not simple:
|
1049
|
+
for export in exported_implemented_functions + asm_runtime_funcs + function_tables:
|
1050
|
+
exports.append("%s: %s" % (export, export))
|
1051
|
+
exports = '{ ' + ', '.join(exports) + ' }'
|
1052
|
+
else:
|
1053
|
+
exports = '_main'
|
1054
|
+
# calculate globals
|
1055
|
+
try:
|
1056
|
+
del forwarded_json['Variables']['globals']['_llvm_global_ctors'] # not a true variable
|
1057
|
+
except:
|
1058
|
+
pass
|
1059
|
+
# If no named globals, only need externals
|
1060
|
+
global_vars = metadata['externs'] #+ forwarded_json['Variables']['globals']
|
1061
|
+
global_funcs = list(set(['_' + key for key, value in forwarded_json['Functions']['libraryFunctions'].iteritems() if value != 2]).difference(set(global_vars)).difference(set(metadata['implementedFunctions'])))
|
1062
|
+
def math_fix(g):
|
1063
|
+
return g if not g.startswith('Math_') else g.split('_')[1]
|
1064
|
+
asm_global_funcs = ''.join([' var ' + g.replace('.', '_') + '=global.' + g + ';\n' for g in maths]) + \
|
1065
|
+
''.join([' var ' + g + '=env.' + math_fix(g) + ';\n' for g in basic_funcs + global_funcs])
|
1066
|
+
asm_global_vars = ''.join([' var ' + g + '=env.' + g + '|0;\n' for g in basic_vars + global_vars])
|
1067
|
+
# In linkable modules, we need to add some explicit globals for global variables that can be linked and used across modules
|
1068
|
+
if settings.get('MAIN_MODULE') or settings.get('SIDE_MODULE'):
|
1069
|
+
assert settings.get('TARGET_LE32'), 'TODO: support x86 target when linking modules (needs offset of 4 and not 8 here)'
|
1070
|
+
for key, value in forwarded_json['Variables']['globals'].iteritems():
|
1071
|
+
if value.get('linkable'):
|
1072
|
+
init = forwarded_json['Variables']['indexedGlobals'][key] + 8 # 8 is Runtime.GLOBAL_BASE / STATIC_BASE
|
1073
|
+
if settings.get('SIDE_MODULE'): init = '(H_BASE+' + str(init) + ')|0'
|
1074
|
+
asm_global_vars += ' var %s=%s;\n' % (key, str(init))
|
1075
|
+
|
1076
|
+
# sent data
|
1077
|
+
the_global = '{ ' + ', '.join(['"' + math_fix(s) + '": ' + s for s in fundamentals]) + ' }'
|
1078
|
+
sending = '{ ' + ', '.join(['"' + math_fix(s) + '": ' + s for s in basic_funcs + global_funcs + basic_vars + basic_float_vars + global_vars]) + ' }'
|
1079
|
+
# received
|
1080
|
+
if not simple:
|
1081
|
+
receiving = ';\n'.join(['var ' + s + ' = Module["' + s + '"] = asm["' + s + '"]' for s in exported_implemented_functions + function_tables])
|
1082
|
+
else:
|
1083
|
+
receiving = 'var _main = Module["_main"] = asm;'
|
1084
|
+
|
1085
|
+
# finalize
|
1086
|
+
|
1087
|
+
if DEBUG: logging.debug('asm text sizes' + str([map(len, funcs_js), len(asm_setup), len(asm_global_vars), len(asm_global_funcs), len(pre_tables), len('\n'.join(function_tables_impls)), len(function_tables_defs.replace('\n', '\n ')), len(exports), len(the_global), len(sending), len(receiving)]))
|
1088
|
+
|
1089
|
+
funcs_js = ['''
|
1090
|
+
%s
|
1091
|
+
function asmPrintInt(x, y) {
|
1092
|
+
Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack);
|
1093
|
+
}
|
1094
|
+
function asmPrintFloat(x, y) {
|
1095
|
+
Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack);
|
1096
|
+
}
|
1097
|
+
// EMSCRIPTEN_START_ASM
|
1098
|
+
var asm = (function(global, env, buffer) {
|
1099
|
+
%s
|
1100
|
+
var HEAP8 = new global.Int8Array(buffer);
|
1101
|
+
var HEAP16 = new global.Int16Array(buffer);
|
1102
|
+
var HEAP32 = new global.Int32Array(buffer);
|
1103
|
+
var HEAPU8 = new global.Uint8Array(buffer);
|
1104
|
+
var HEAPU16 = new global.Uint16Array(buffer);
|
1105
|
+
var HEAPU32 = new global.Uint32Array(buffer);
|
1106
|
+
var HEAPF32 = new global.Float32Array(buffer);
|
1107
|
+
var HEAPF64 = new global.Float64Array(buffer);
|
1108
|
+
''' % (asm_setup, "'use asm';" if not metadata.get('hasInlineJS') and not settings['SIDE_MODULE'] and settings['ASM_JS'] == 1 else "'almost asm';") + '\n' + asm_global_vars + '''
|
1109
|
+
var __THREW__ = 0;
|
1110
|
+
var threwValue = 0;
|
1111
|
+
var setjmpId = 0;
|
1112
|
+
var undef = 0;
|
1113
|
+
var nan = +env.NaN, inf = +env.Infinity;
|
1114
|
+
var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
|
1115
|
+
''' + ''.join(['''
|
1116
|
+
var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs] + [' var tempFloat = %s;\n' % ('Math_fround(0)' if settings.get('PRECISE_F32') else '0.0')] + ['''
|
1117
|
+
// EMSCRIPTEN_START_FUNCS
|
1118
|
+
function stackAlloc(size) {
|
1119
|
+
size = size|0;
|
1120
|
+
var ret = 0;
|
1121
|
+
ret = STACKTOP;
|
1122
|
+
STACKTOP = (STACKTOP + size)|0;
|
1123
|
+
''' + ('STACKTOP = (STACKTOP + 3)&-4;' if settings['TARGET_X86'] else 'STACKTOP = (STACKTOP + 7)&-8;') + '''
|
1124
|
+
return ret|0;
|
1125
|
+
}
|
1126
|
+
function stackSave() {
|
1127
|
+
return STACKTOP|0;
|
1128
|
+
}
|
1129
|
+
function stackRestore(top) {
|
1130
|
+
top = top|0;
|
1131
|
+
STACKTOP = top;
|
1132
|
+
}
|
1133
|
+
function setThrew(threw, value) {
|
1134
|
+
threw = threw|0;
|
1135
|
+
value = value|0;
|
1136
|
+
if ((__THREW__|0) == 0) {
|
1137
|
+
__THREW__ = threw;
|
1138
|
+
threwValue = value;
|
1139
|
+
}
|
1140
|
+
}
|
1141
|
+
function copyTempFloat(ptr) {
|
1142
|
+
ptr = ptr|0;
|
1143
|
+
HEAP8[tempDoublePtr] = HEAP8[ptr];
|
1144
|
+
HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0];
|
1145
|
+
HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0];
|
1146
|
+
HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0];
|
1147
|
+
}
|
1148
|
+
function copyTempDouble(ptr) {
|
1149
|
+
ptr = ptr|0;
|
1150
|
+
HEAP8[tempDoublePtr] = HEAP8[ptr];
|
1151
|
+
HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0];
|
1152
|
+
HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0];
|
1153
|
+
HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0];
|
1154
|
+
HEAP8[tempDoublePtr+4|0] = HEAP8[ptr+4|0];
|
1155
|
+
HEAP8[tempDoublePtr+5|0] = HEAP8[ptr+5|0];
|
1156
|
+
HEAP8[tempDoublePtr+6|0] = HEAP8[ptr+6|0];
|
1157
|
+
HEAP8[tempDoublePtr+7|0] = HEAP8[ptr+7|0];
|
1158
|
+
}
|
1159
|
+
''' + ''.join(['''
|
1160
|
+
function setTempRet%d(value) {
|
1161
|
+
value = value|0;
|
1162
|
+
tempRet%d = value;
|
1163
|
+
}
|
1164
|
+
''' % (i, i) for i in range(10)])] + funcs_js + ['''
|
1165
|
+
%s
|
1166
|
+
|
1167
|
+
return %s;
|
1168
|
+
})
|
1169
|
+
// EMSCRIPTEN_END_ASM
|
1170
|
+
(%s, %s, buffer);
|
1171
|
+
%s;
|
1172
|
+
''' % (pre_tables + '\n'.join(function_tables_impls) + '\n' + function_tables_defs.replace('\n', '\n '), exports, the_global, sending, receiving)]
|
1173
|
+
|
1174
|
+
if not settings.get('SIDE_MODULE'):
|
1175
|
+
funcs_js.append('''
|
1176
|
+
Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) };
|
1177
|
+
Runtime.stackSave = function() { return asm['stackSave']() };
|
1178
|
+
Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
|
1179
|
+
''')
|
1180
|
+
|
1181
|
+
# Set function table masks
|
1182
|
+
masks = {}
|
1183
|
+
max_mask = 0
|
1184
|
+
for sig, table in last_forwarded_json['Functions']['tables'].iteritems():
|
1185
|
+
mask = table.count(',')
|
1186
|
+
masks[sig] = str(mask)
|
1187
|
+
max_mask = max(mask, max_mask)
|
1188
|
+
def function_table_maskize(js, masks):
|
1189
|
+
def fix(m):
|
1190
|
+
sig = m.groups(0)[0]
|
1191
|
+
return masks[sig]
|
1192
|
+
return re.sub(r'{{{ FTM_([\w\d_$]+) }}}', lambda m: fix(m), js) # masks[m.groups(0)[0]]
|
1193
|
+
funcs_js = map(lambda js: function_table_maskize(js, masks), funcs_js)
|
1194
|
+
|
1195
|
+
if settings.get('DLOPEN_SUPPORT'):
|
1196
|
+
funcs_js.append('''
|
1197
|
+
asm.maxFunctionIndex = %(max_mask)d;
|
1198
|
+
DLFCN.registerFunctions(asm, %(max_mask)d+1, %(sigs)s, Module);
|
1199
|
+
Module.SYMBOL_TABLE = SYMBOL_TABLE;
|
1200
|
+
''' % { 'max_mask': max_mask, 'sigs': str(map(str, last_forwarded_json['Functions']['tables'].keys())) })
|
1201
|
+
|
1202
|
+
else:
|
1203
|
+
function_tables_defs = '\n'.join([table for table in last_forwarded_json['Functions']['tables'].itervalues()])
|
1204
|
+
outfile.write(function_tables_defs)
|
1205
|
+
funcs_js = ['''
|
1206
|
+
// EMSCRIPTEN_START_FUNCS
|
1207
|
+
'''] + funcs_js + ['''
|
1208
|
+
// EMSCRIPTEN_END_FUNCS
|
1209
|
+
''']
|
1210
|
+
|
1211
|
+
# Create symbol table for self-dlopen
|
1212
|
+
if settings.get('DLOPEN_SUPPORT'):
|
1213
|
+
symbol_table = {}
|
1214
|
+
for k, v in forwarded_json['Variables']['indexedGlobals'].iteritems():
|
1215
|
+
if forwarded_json['Variables']['globals'][k]['named']:
|
1216
|
+
symbol_table[k] = str(v + forwarded_json['Runtime']['GLOBAL_BASE'])
|
1217
|
+
for raw in last_forwarded_json['Functions']['tables'].itervalues():
|
1218
|
+
if raw == '': continue
|
1219
|
+
table = map(string.strip, raw[raw.find('[')+1:raw.find(']')].split(","))
|
1220
|
+
for i in range(len(table)):
|
1221
|
+
value = table[i]
|
1222
|
+
if value != '0':
|
1223
|
+
if settings.get('SIDE_MODULE'):
|
1224
|
+
symbol_table[value] = 'FUNCTION_TABLE_OFFSET+' + str(i)
|
1225
|
+
else:
|
1226
|
+
symbol_table[value] = str(i)
|
1227
|
+
outfile.write("var SYMBOL_TABLE = %s;" % json.dumps(symbol_table).replace('"', ''))
|
1228
|
+
|
1229
|
+
for i in range(len(funcs_js)): # do this loop carefully to save memory
|
1230
|
+
outfile.write(funcs_js[i])
|
1231
|
+
funcs_js = None
|
1232
|
+
|
1233
|
+
outfile.write(post)
|
1234
|
+
|
1235
|
+
outfile.close()
|
1236
|
+
|
1237
|
+
if DEBUG: logging.debug(' emscript: final python processing took %s seconds' % (time.time() - t))
|
1238
|
+
|
1239
|
+
if os.environ.get('EMCC_FAST_COMPILER'):
|
1240
|
+
emscript = emscript_fast
|
1241
|
+
|
714
1242
|
def main(args, compiler_engine, cache, jcache, relooper, temp_files, DEBUG, DEBUG_CACHE):
|
715
1243
|
# Prepare settings for serialization to JSON.
|
716
1244
|
settings = {}
|
@@ -727,14 +1255,12 @@ def main(args, compiler_engine, cache, jcache, relooper, temp_files, DEBUG, DEBU
|
|
727
1255
|
relooper = cache.get_path('relooper.js')
|
728
1256
|
settings.setdefault('RELOOPER', relooper)
|
729
1257
|
if not os.path.exists(relooper):
|
730
|
-
from tools import shared
|
731
1258
|
shared.Building.ensure_relooper(relooper)
|
732
1259
|
|
733
1260
|
settings.setdefault('STRUCT_INFO', cache.get_path('struct_info.compiled.json'))
|
734
1261
|
struct_info = settings.get('STRUCT_INFO')
|
735
1262
|
|
736
1263
|
if not os.path.exists(struct_info):
|
737
|
-
from tools import shared
|
738
1264
|
shared.Building.ensure_struct_info(struct_info)
|
739
1265
|
|
740
1266
|
emscript(args.infile, settings, args.outfile, libraries, compiler_engine=compiler_engine,
|
@@ -833,7 +1359,6 @@ WARNING: You should normally never use this! Use emcc instead.
|
|
833
1359
|
temp_files = tempfiles.TempFiles(temp_dir)
|
834
1360
|
|
835
1361
|
if keywords.compiler is None:
|
836
|
-
from tools import shared
|
837
1362
|
keywords.compiler = shared.COMPILER_ENGINE
|
838
1363
|
|
839
1364
|
if keywords.verbose is None:
|