webruby 0.2.2 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -618,6 +618,7 @@ function simplifyExpressions(ast) {
|
|
618
618
|
|
619
619
|
if (asm) {
|
620
620
|
if (hasTempDoublePtr) {
|
621
|
+
var asmData = normalizeAsm(ast);
|
621
622
|
traverse(ast, function(node, type) {
|
622
623
|
if (type === 'assign') {
|
623
624
|
if (node[1] === true && node[2][0] === 'sub' && node[2][1][0] === 'name' && node[2][1][1] === 'HEAP32') {
|
@@ -642,7 +643,7 @@ function simplifyExpressions(ast) {
|
|
642
643
|
node[2][0] !== 'seq') { // avoid (x, y, z) which can be used for tempDoublePtr on doubles for alignment fixes
|
643
644
|
if (node[1][2][1][1] === 'HEAP32') {
|
644
645
|
node[1][3][1][1] = 'HEAPF32';
|
645
|
-
return
|
646
|
+
return makeAsmCoercion(node[1][3], detectAsmCoercion(node[2]));
|
646
647
|
} else {
|
647
648
|
node[1][3][1][1] = 'HEAP32';
|
648
649
|
return ['binary', '|', node[1][3], ['num', 0]];
|
@@ -686,7 +687,6 @@ function simplifyExpressions(ast) {
|
|
686
687
|
}
|
687
688
|
}
|
688
689
|
});
|
689
|
-
var asmData = normalizeAsm(ast);
|
690
690
|
for (var v in bitcastVars) {
|
691
691
|
var info = bitcastVars[v];
|
692
692
|
// good variables define only one type, use only one type, have definitions and uses, and define as a different type than they use
|
@@ -1142,13 +1142,28 @@ function simplifyNotComps(ast) {
|
|
1142
1142
|
simplifyNotCompsPass = false;
|
1143
1143
|
}
|
1144
1144
|
|
1145
|
-
|
1145
|
+
function callHasSideEffects(node) { // checks if the call itself (not the args) has side effects (or is not statically known)
|
1146
|
+
return !(node[1][0] === 'name' && /^Math_/.test(node[1][1]));
|
1147
|
+
}
|
1146
1148
|
|
1147
1149
|
function hasSideEffects(node) { // this is 99% incomplete!
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1150
|
+
switch (node[0]) {
|
1151
|
+
case 'num': case 'name': case 'string': return false;
|
1152
|
+
case 'unary-prefix': return hasSideEffects(node[2]);
|
1153
|
+
case 'binary': return hasSideEffects(node[2]) || hasSideEffects(node[3]);
|
1154
|
+
case 'sub': return hasSideEffects(node[1]) || hasSideEffects(node[2]);
|
1155
|
+
case 'call': {
|
1156
|
+
if (callHasSideEffects(node)) return true;
|
1157
|
+
// This is a statically known call, with no side effects. only args can side effect us
|
1158
|
+
var args = node[2];
|
1159
|
+
var num = args.length;
|
1160
|
+
for (var i = 0; i < num; i++) {
|
1161
|
+
if (hasSideEffects(args[i])) return true;
|
1162
|
+
}
|
1163
|
+
return false;
|
1164
|
+
}
|
1165
|
+
default: return true;
|
1166
|
+
}
|
1152
1167
|
}
|
1153
1168
|
|
1154
1169
|
// Clear out empty ifs and blocks, and redundant blocks/stats and so forth
|
@@ -1515,21 +1530,33 @@ function unVarify(vars, ret) { // transform var x=1, y=2 etc. into (x=1, y=2), i
|
|
1515
1530
|
// annotations, plus explicit metadata) and denormalize (vice versa)
|
1516
1531
|
var ASM_INT = 0;
|
1517
1532
|
var ASM_DOUBLE = 1;
|
1533
|
+
var ASM_FLOAT = 2;
|
1518
1534
|
|
1519
1535
|
function detectAsmCoercion(node, asmInfo) {
|
1520
1536
|
// for params, +x vs x|0, for vars, 0.0 vs 0
|
1521
1537
|
if (node[0] === 'num' && node[1].toString().indexOf('.') >= 0) return ASM_DOUBLE;
|
1522
1538
|
if (node[0] === 'unary-prefix') return ASM_DOUBLE;
|
1539
|
+
if (node[0] === 'call' && node[1][0] === 'name' && node[1][1] === 'Math_fround') return ASM_FLOAT;
|
1523
1540
|
if (asmInfo && node[0] == 'name') return getAsmType(node[1], asmInfo);
|
1524
1541
|
return ASM_INT;
|
1525
1542
|
}
|
1526
1543
|
|
1527
1544
|
function makeAsmCoercion(node, type) {
|
1528
|
-
|
1545
|
+
switch (type) {
|
1546
|
+
case ASM_INT: return ['binary', '|', node, ['num', 0]];
|
1547
|
+
case ASM_DOUBLE: return ['unary-prefix', '+', node];
|
1548
|
+
case ASM_FLOAT: return ['call', ['name', 'Math_fround'], [node]];
|
1549
|
+
default: throw 'wha? ' + JSON.stringify([node, type]) + new Error().stack;
|
1550
|
+
}
|
1529
1551
|
}
|
1530
1552
|
|
1531
1553
|
function makeAsmVarDef(v, type) {
|
1532
|
-
|
1554
|
+
switch (type) {
|
1555
|
+
case ASM_INT: return [v, ['num', 0]];
|
1556
|
+
case ASM_DOUBLE: return [v, ['unary-prefix', '+', ['num', 0]]];
|
1557
|
+
case ASM_FLOAT: return [v, ['call', ['name', 'Math_fround'], [['num', 0]]]];
|
1558
|
+
default: throw 'wha?';
|
1559
|
+
}
|
1533
1560
|
}
|
1534
1561
|
|
1535
1562
|
function getAsmType(name, asmInfo) {
|
@@ -1568,7 +1595,8 @@ function normalizeAsm(func) {
|
|
1568
1595
|
var name = v[0];
|
1569
1596
|
var value = v[1];
|
1570
1597
|
if (!(name in data.vars)) {
|
1571
|
-
assert(value[0] === 'num' || (value[0] === 'unary-prefix' && value[2][0] === 'num')
|
1598
|
+
assert(value[0] === 'num' || (value[0] === 'unary-prefix' && value[2][0] === 'num') // must be valid coercion no-op
|
1599
|
+
|| (value[0] === 'call' && value[1][0] === 'name' && value[1][1] === 'Math_fround'));
|
1572
1600
|
data.vars[name] = detectAsmCoercion(value);
|
1573
1601
|
v.length = 1; // make an un-assigning var
|
1574
1602
|
} else {
|
@@ -1917,7 +1945,7 @@ function registerize(ast) {
|
|
1917
1945
|
// we just use a fresh register to make sure we avoid this, but it could be
|
1918
1946
|
// optimized to check for safe registers (free, and not used in this loop level).
|
1919
1947
|
var varRegs = {}; // maps variables to the register they will use all their life
|
1920
|
-
var freeRegsClasses = asm ? [[], []] : []; // two classes for asm, one otherwise
|
1948
|
+
var freeRegsClasses = asm ? [[], [], []] : []; // two classes for asm, one otherwise XXX - hardcoded length
|
1921
1949
|
var nextReg = 1;
|
1922
1950
|
var fullNames = {};
|
1923
1951
|
var loopRegs = {}; // for each loop nesting level, the list of bound variables
|
@@ -2031,6 +2059,33 @@ function registerize(ast) {
|
|
2031
2059
|
}
|
2032
2060
|
}
|
2033
2061
|
denormalizeAsm(fun, finalAsmData);
|
2062
|
+
if (extraInfo && extraInfo.globals) {
|
2063
|
+
// minify in asm var definitions, that denormalizeAsm just generated
|
2064
|
+
function minify(value) {
|
2065
|
+
if (value && value[0] === 'call' && value[1][0] === 'name') {
|
2066
|
+
var name = value[1][1];
|
2067
|
+
var minified = extraInfo.globals[name];
|
2068
|
+
if (minified) {
|
2069
|
+
value[1][1] = minified;
|
2070
|
+
}
|
2071
|
+
}
|
2072
|
+
}
|
2073
|
+
var stats = fun[3];
|
2074
|
+
for (var i = 0; i < stats.length; i++) {
|
2075
|
+
var line = stats[i];
|
2076
|
+
if (i >= fun[2].length && line[0] !== 'var') break; // when we pass the arg and var coercions, break
|
2077
|
+
if (line[0] === 'stat') {
|
2078
|
+
assert(line[1][0] === 'assign');
|
2079
|
+
minify(line[1][3]);
|
2080
|
+
} else {
|
2081
|
+
assert(line[0] === 'var');
|
2082
|
+
var pairs = line[1];
|
2083
|
+
for (var j = 0; j < pairs.length; j++) {
|
2084
|
+
minify(pairs[j][1]);
|
2085
|
+
}
|
2086
|
+
}
|
2087
|
+
}
|
2088
|
+
}
|
2034
2089
|
}
|
2035
2090
|
});
|
2036
2091
|
}
|
@@ -2068,7 +2123,6 @@ function registerize(ast) {
|
|
2068
2123
|
// can happen in ALLOW_MEMORY_GROWTH mode
|
2069
2124
|
|
2070
2125
|
var ELIMINATION_SAFE_NODES = set('var', 'assign', 'call', 'if', 'toplevel', 'do', 'return', 'label', 'switch'); // do is checked carefully, however
|
2071
|
-
var NODES_WITHOUT_ELIMINATION_SIDE_EFFECTS = set('name', 'num', 'string', 'binary', 'sub', 'unary-prefix');
|
2072
2126
|
var IGNORABLE_ELIMINATOR_SCAN_NODES = set('num', 'toplevel', 'string', 'break', 'continue', 'dot'); // dot can only be STRING_TABLE.*
|
2073
2127
|
var ABORTING_ELIMINATOR_SCAN_NODES = set('new', 'object', 'function', 'defun', 'for', 'while', 'array', 'throw'); // we could handle some of these, TODO, but nontrivial (e.g. for while, the condition is hit multiple times after the body)
|
2074
2128
|
|
@@ -2160,7 +2214,7 @@ function eliminate(ast, memSafe) {
|
|
2160
2214
|
if (definitions[name] === 1 && uses[name] === 1) {
|
2161
2215
|
potentials[name] = 1;
|
2162
2216
|
} else if (uses[name] === 0 && (!definitions[name] || definitions[name] <= 1)) { // no uses, no def or 1 def (cannot operate on phis, and the llvm optimizer will remove unneeded phis anyhow) (no definition means it is a function parameter, or a local with just |var x;| but no defining assignment)
|
2163
|
-
var
|
2217
|
+
var sideEffects = false;
|
2164
2218
|
var value = values[name];
|
2165
2219
|
if (value) {
|
2166
2220
|
// TODO: merge with other side effect code
|
@@ -2170,15 +2224,10 @@ function eliminate(ast, memSafe) {
|
|
2170
2224
|
if (!(value[0] === 'seq' && value[1][0] === 'assign' && value[1][2][0] === 'sub' && value[1][2][2][0] === 'binary' && value[1][2][2][1] === '>>' &&
|
2171
2225
|
value[1][2][2][2][0] === 'name' && value[1][2][2][2][1] === 'tempDoublePtr')) {
|
2172
2226
|
// If not that, then traverse and scan normally.
|
2173
|
-
|
2174
|
-
if (!(type in NODES_WITHOUT_ELIMINATION_SIDE_EFFECTS)) {
|
2175
|
-
hasSideEffects = true; // cannot remove this unused variable, constructing it has side effects
|
2176
|
-
return true;
|
2177
|
-
}
|
2178
|
-
});
|
2227
|
+
sideEffects = hasSideEffects(value);
|
2179
2228
|
}
|
2180
2229
|
}
|
2181
|
-
if (!
|
2230
|
+
if (!sideEffects) {
|
2182
2231
|
varsToRemove[name] = !definitions[name] ? 2 : 1; // remove it normally
|
2183
2232
|
sideEffectFree[name] = true;
|
2184
2233
|
// Each time we remove a variable with 0 uses, if its value has no
|
@@ -2437,14 +2486,16 @@ function eliminate(ast, memSafe) {
|
|
2437
2486
|
for (var i = 0; i < args.length; i++) {
|
2438
2487
|
traverseInOrder(args[i]);
|
2439
2488
|
}
|
2440
|
-
|
2441
|
-
|
2442
|
-
|
2443
|
-
|
2444
|
-
|
2445
|
-
|
2446
|
-
|
2447
|
-
|
2489
|
+
if (callHasSideEffects(node)) {
|
2490
|
+
// these two invalidations will also invalidate calls
|
2491
|
+
if (!globalsInvalidated) {
|
2492
|
+
invalidateGlobals();
|
2493
|
+
globalsInvalidated = true;
|
2494
|
+
}
|
2495
|
+
if (!memoryInvalidated) {
|
2496
|
+
invalidateMemory();
|
2497
|
+
memoryInvalidated = true;
|
2498
|
+
}
|
2448
2499
|
}
|
2449
2500
|
} else if (type === 'if') {
|
2450
2501
|
if (allowTracking) {
|
@@ -2485,6 +2536,10 @@ function eliminate(ast, memSafe) {
|
|
2485
2536
|
} else if (type === 'return') {
|
2486
2537
|
if (node[1]) traverseInOrder(node[1]);
|
2487
2538
|
} else if (type === 'conditional') {
|
2539
|
+
if (!callsInvalidated) { // invalidate calls, since we cannot eliminate them into a branch of an LLVM select/JS conditional that does not execute
|
2540
|
+
invalidateCalls();
|
2541
|
+
callsInvalidated = true;
|
2542
|
+
}
|
2488
2543
|
traverseInOrder(node[1]);
|
2489
2544
|
traverseInOrder(node[2]);
|
2490
2545
|
traverseInOrder(node[3]);
|
@@ -3169,7 +3224,7 @@ function outline(ast) {
|
|
3169
3224
|
|
3170
3225
|
var writes = {};
|
3171
3226
|
var namings = {};
|
3172
|
-
var hasReturn = false,
|
3227
|
+
var hasReturn = false, hasReturnType = {}, hasBreak = false, hasContinue = false;
|
3173
3228
|
var breaks = {}; // set of labels we break or continue
|
3174
3229
|
var continues = {}; // to (name -> id, just like labels)
|
3175
3230
|
var breakCapturers = 0;
|
@@ -3189,10 +3244,8 @@ function outline(ast) {
|
|
3189
3244
|
} else if (type == 'return') {
|
3190
3245
|
if (!node[1]) {
|
3191
3246
|
hasReturn = true;
|
3192
|
-
} else if (detectAsmCoercion(node[1]) == ASM_INT) {
|
3193
|
-
hasReturnInt = true;
|
3194
3247
|
} else {
|
3195
|
-
|
3248
|
+
hasReturnType[detectAsmCoercion(node[1])] = true;
|
3196
3249
|
}
|
3197
3250
|
} else if (type == 'break') {
|
3198
3251
|
var label = node[1] || 0;
|
@@ -3222,7 +3275,6 @@ function outline(ast) {
|
|
3222
3275
|
continueCapturers--;
|
3223
3276
|
}
|
3224
3277
|
});
|
3225
|
-
assert(hasReturn + hasReturnInt + hasReturnDouble <= 1);
|
3226
3278
|
|
3227
3279
|
var reads = {};
|
3228
3280
|
for (var v in namings) {
|
@@ -3230,7 +3282,7 @@ function outline(ast) {
|
|
3230
3282
|
if (actualReads > 0) reads[v] = actualReads;
|
3231
3283
|
}
|
3232
3284
|
|
3233
|
-
return { writes: writes, reads: reads, hasReturn: hasReturn,
|
3285
|
+
return { writes: writes, reads: reads, hasReturn: hasReturn, hasReturnType: hasReturnType, hasBreak: hasBreak, hasContinue: hasContinue, breaks: breaks, continues: continues, labels: labels };
|
3234
3286
|
}
|
3235
3287
|
|
3236
3288
|
function makeAssign(dst, src) {
|
@@ -3251,7 +3303,10 @@ function outline(ast) {
|
|
3251
3303
|
return ['switch', value, cases];
|
3252
3304
|
}
|
3253
3305
|
|
3254
|
-
var CONTROL_BREAK = 1, CONTROL_BREAK_LABEL = 2, CONTROL_CONTINUE = 3, CONTROL_CONTINUE_LABEL = 4, CONTROL_RETURN_VOID = 5, CONTROL_RETURN_INT = 6, CONTROL_RETURN_DOUBLE = 7;
|
3306
|
+
var CONTROL_BREAK = 1, CONTROL_BREAK_LABEL = 2, CONTROL_CONTINUE = 3, CONTROL_CONTINUE_LABEL = 4, CONTROL_RETURN_VOID = 5, CONTROL_RETURN_INT = 6, CONTROL_RETURN_DOUBLE = 7, CONTROL_RETURN_FLOAT = 8;
|
3307
|
+
function controlFromAsmType(asmType) {
|
3308
|
+
return CONTROL_RETURN_INT + (asmType | 0); // assumes ASM_INT starts at 0, and order of these two is identical!
|
3309
|
+
}
|
3255
3310
|
|
3256
3311
|
var sizeToOutline = null; // customized per function and as we make progress
|
3257
3312
|
function calculateThreshold(func, asmData) {
|
@@ -3310,7 +3365,7 @@ function outline(ast) {
|
|
3310
3365
|
});
|
3311
3366
|
|
3312
3367
|
// Generate new function
|
3313
|
-
if (codeInfo.hasReturn || codeInfo.
|
3368
|
+
if (codeInfo.hasReturn || codeInfo.hasReturnType[ASM_INT] || codeInfo.hasReturnType[ASM_DOUBLE] || codeInfo.hasReturnType[ASM_FLOAT] || codeInfo.hasBreak || codeInfo.hasContinue) {
|
3314
3369
|
// we need to capture all control flow using a top-level labeled one-time loop in the outlined function
|
3315
3370
|
var breakCapturers = 0;
|
3316
3371
|
var continueCapturers = 0;
|
@@ -3335,7 +3390,7 @@ function outline(ast) {
|
|
3335
3390
|
ret.push(['stat', makeAssign(makeStackAccess(ASM_INT, asmData.controlStackPos(outlineIndex)), ['num', CONTROL_RETURN_VOID])]);
|
3336
3391
|
} else {
|
3337
3392
|
var type = detectAsmCoercion(node[1], asmData);
|
3338
|
-
ret.push(['stat', makeAssign(makeStackAccess(ASM_INT, asmData.controlStackPos(outlineIndex)), ['num', type
|
3393
|
+
ret.push(['stat', makeAssign(makeStackAccess(ASM_INT, asmData.controlStackPos(outlineIndex)), ['num', controlFromAsmType(type)])]);
|
3339
3394
|
ret.push(['stat', makeAssign(makeStackAccess(type, asmData.controlDataStackPos(outlineIndex)), node[1])]);
|
3340
3395
|
}
|
3341
3396
|
ret.push(['stat', ['break', 'OL']]);
|
@@ -3398,16 +3453,10 @@ function outline(ast) {
|
|
3398
3453
|
[['stat', ['return']]]
|
3399
3454
|
));
|
3400
3455
|
}
|
3401
|
-
|
3456
|
+
for (var returnType in codeInfo.hasReturnType) {
|
3402
3457
|
reps.push(makeIf(
|
3403
|
-
makeComparison(makeAsmCoercion(['name', 'tempValue'], ASM_INT), '==', ['num',
|
3404
|
-
[['stat', ['return', makeAsmCoercion(['name', 'tempInt'],
|
3405
|
-
));
|
3406
|
-
}
|
3407
|
-
if (codeInfo.hasReturnDouble) {
|
3408
|
-
reps.push(makeIf(
|
3409
|
-
makeComparison(makeAsmCoercion(['name', 'tempValue'], ASM_INT), '==', ['num', CONTROL_RETURN_DOUBLE]),
|
3410
|
-
[['stat', ['return', makeAsmCoercion(['name', 'tempDouble'], ASM_DOUBLE)]]]
|
3458
|
+
makeComparison(makeAsmCoercion(['name', 'tempValue'], ASM_INT), '==', ['num', controlFromAsmType(returnType)]),
|
3459
|
+
[['stat', ['return', makeAsmCoercion(['name', 'tempInt'], returnType | 0)]]]
|
3411
3460
|
));
|
3412
3461
|
}
|
3413
3462
|
if (codeInfo.hasBreak) {
|
@@ -3486,8 +3535,9 @@ function outline(ast) {
|
|
3486
3535
|
var last = getStatements(func)[getStatements(func).length-1];
|
3487
3536
|
if (last[0] === 'stat') last = last[1];
|
3488
3537
|
if (last[0] !== 'return') {
|
3489
|
-
|
3490
|
-
getStatements(func).push(['stat', ['return', makeAsmCoercion(['num', 0],
|
3538
|
+
for (var returnType in codeInfo.hasReturnType) {
|
3539
|
+
getStatements(func).push(['stat', ['return', makeAsmCoercion(['num', 0], returnType | 0)]]);
|
3540
|
+
break;
|
3491
3541
|
}
|
3492
3542
|
}
|
3493
3543
|
outliningParents[newIdent] = func[1];
|
@@ -29,13 +29,13 @@ class Minifier:
|
|
29
29
|
during registerize perform minification of locals.
|
30
30
|
'''
|
31
31
|
|
32
|
-
def __init__(self, js, js_engine):
|
32
|
+
def __init__(self, js, js_engine, MAX_NAMES):
|
33
33
|
self.js = js
|
34
34
|
self.js_engine = js_engine
|
35
|
+
MAX_NAMES = min(MAX_NAMES, 120000)
|
35
36
|
|
36
37
|
# Create list of valid short names
|
37
38
|
|
38
|
-
MAX_NAMES = 80000
|
39
39
|
INVALID_2 = set(['do', 'if', 'in'])
|
40
40
|
INVALID_3 = set(['for', 'new', 'try', 'var', 'env', 'let'])
|
41
41
|
|
@@ -56,7 +56,6 @@ class Minifier:
|
|
56
56
|
if len(self.names) >= MAX_NAMES: break
|
57
57
|
curr = a + b + c
|
58
58
|
if curr not in INVALID_3: self.names.append(curr)
|
59
|
-
#print >> sys.stderr, self.names
|
60
59
|
|
61
60
|
def minify_shell(self, shell, minify_whitespace, source_map=False):
|
62
61
|
#print >> sys.stderr, "MINIFY SHELL 1111111111", shell, "\n222222222222222"
|
@@ -187,7 +186,8 @@ EMSCRIPTEN_FUNCS();
|
|
187
186
|
''' + js[end_funcs + len(end_funcs_marker):end_asm + len(end_asm_marker)]
|
188
187
|
js = js[start_funcs + len(start_funcs_marker):end_funcs]
|
189
188
|
|
190
|
-
|
189
|
+
# we assume there is a maximum of one new name per line
|
190
|
+
minifier = Minifier(js, js_engine, js.count('\n') + asm_shell.count('\n'))
|
191
191
|
asm_shell_pre, asm_shell_post = minifier.minify_shell(asm_shell, 'minifyWhitespace' in passes, source_map).split('EMSCRIPTEN_FUNCS();');
|
192
192
|
asm_shell_post = asm_shell_post.replace('});', '})');
|
193
193
|
pre += asm_shell_pre + '\n' + start_funcs_marker
|
Binary file
|
@@ -3,7 +3,7 @@ from subprocess import Popen, PIPE, STDOUT
|
|
3
3
|
|
4
4
|
TRACK_PROCESS_SPAWNS = True if (os.getenv('EM_BUILD_VERBOSE') and int(os.getenv('EM_BUILD_VERBOSE')) >= 3) else False
|
5
5
|
|
6
|
-
def timeout_run(proc, timeout, note='unnamed process', full_output=False):
|
6
|
+
def timeout_run(proc, timeout=None, note='unnamed process', full_output=False):
|
7
7
|
start = time.time()
|
8
8
|
if timeout is not None:
|
9
9
|
while time.time() - start < timeout and proc.poll() is None:
|
Binary file
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import tempfile, os, sys, shlex
|
2
|
+
import shared
|
2
3
|
|
3
4
|
# Routes the given cmdline param list in args into a new response file and returns the filename to it.
|
4
5
|
# The returned filename has a suffix '.rsp'.
|
@@ -9,6 +10,11 @@ def create_response_file(args, directory):
|
|
9
10
|
args = map(lambda p: p.replace('\\', '\\\\').replace('"', '\\"'), args)
|
10
11
|
response_fd.write('"' + '" "'.join(args) + '"')
|
11
12
|
response_fd.close()
|
13
|
+
|
14
|
+
# Register the created .rsp file to be automatically cleaned up once this process finishes, so that
|
15
|
+
# caller does not have to remember to do it.
|
16
|
+
shared.configuration.get_temp_files().note(response_filename)
|
17
|
+
|
12
18
|
return response_filename
|
13
19
|
|
14
20
|
# Reads a response file, and returns the list of cmdline params found in the file.
|
Binary file
|
@@ -18,6 +18,8 @@ JAVA = 'java' # executable
|
|
18
18
|
|
19
19
|
TEMP_DIR = '{{{ TEMP }}}'
|
20
20
|
|
21
|
+
CRUNCH = os.path.expanduser(os.getenv('CRUNCH') or 'crunch') # executable
|
22
|
+
|
21
23
|
#CLOSURE_COMPILER = '..' # define this to not use the bundled version
|
22
24
|
|
23
25
|
########################################################################################################
|
@@ -1,9 +1,9 @@
|
|
1
|
-
import shutil, time, os, sys, json, tempfile, copy, shlex, atexit, subprocess, hashlib, cPickle, re
|
1
|
+
import shutil, time, os, sys, json, tempfile, copy, shlex, atexit, subprocess, hashlib, cPickle, re, errno
|
2
2
|
from subprocess import Popen, PIPE, STDOUT
|
3
3
|
from tempfile import mkstemp
|
4
4
|
from distutils.spawn import find_executable
|
5
5
|
import jsrun, cache, tempfiles
|
6
|
-
|
6
|
+
import response_file
|
7
7
|
import logging, platform
|
8
8
|
|
9
9
|
def listify(x):
|
@@ -41,8 +41,8 @@ class WindowsPopen:
|
|
41
41
|
# emscripten.py supports reading args from a response file instead of cmdline.
|
42
42
|
# Use .rsp to avoid cmdline length limitations on Windows.
|
43
43
|
if len(args) >= 2 and args[1].endswith("emscripten.py"):
|
44
|
-
|
45
|
-
args = args[0:2] + ['@' +
|
44
|
+
response_filename = response_file.create_response_file(args[2:], TEMP_DIR)
|
45
|
+
args = args[0:2] + ['@' + response_filename]
|
46
46
|
|
47
47
|
try:
|
48
48
|
# Call the process with fixed streams.
|
@@ -78,13 +78,6 @@ class WindowsPopen:
|
|
78
78
|
def kill(self):
|
79
79
|
return self.process.kill()
|
80
80
|
|
81
|
-
def __del__(self):
|
82
|
-
try:
|
83
|
-
# Clean up the temporary response file that was used to spawn this process, so that we don't leave temp files around.
|
84
|
-
tempfiles.try_delete(self.response_filename)
|
85
|
-
except:
|
86
|
-
pass # Mute all exceptions in dtor, particularly if we didn't use a response file, self.response_filename doesn't exist.
|
87
|
-
|
88
81
|
__rootpath__ = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
|
89
82
|
def path_from_root(*pathelems):
|
90
83
|
return os.path.join(__rootpath__, *pathelems)
|
@@ -183,13 +176,28 @@ if WINDOWS:
|
|
183
176
|
else:
|
184
177
|
logging.StreamHandler.emit = add_coloring_to_emit_ansi(logging.StreamHandler.emit)
|
185
178
|
|
186
|
-
# Emscripten configuration is done through the
|
187
|
-
#
|
188
|
-
# separated definitions, then these definitions will be used to configure
|
179
|
+
# Emscripten configuration is done through the --em-config command line option or
|
180
|
+
# the EM_CONFIG environment variable. If the specified string value contains newline
|
181
|
+
# or semicolon-separated definitions, then these definitions will be used to configure
|
189
182
|
# Emscripten. Otherwise, the string is understood to be a path to a settings
|
190
183
|
# file that contains the required definitions.
|
191
184
|
|
192
|
-
|
185
|
+
try:
|
186
|
+
EM_CONFIG = sys.argv[sys.argv.index('--em-config')+1]
|
187
|
+
# Emscripten compiler spawns other processes, which can reimport shared.py, so make sure that
|
188
|
+
# those child processes get the same configuration file by setting it to the currently active environment.
|
189
|
+
os.environ['EM_CONFIG'] = EM_CONFIG
|
190
|
+
except:
|
191
|
+
EM_CONFIG = os.environ.get('EM_CONFIG')
|
192
|
+
|
193
|
+
if EM_CONFIG and not os.path.isfile(EM_CONFIG):
|
194
|
+
if EM_CONFIG.startswith('-'):
|
195
|
+
raise Exception('Passed --em-config without an argument. Usage: --em-config /path/to/.emscripten or --em-config EMSCRIPTEN_ROOT=/path/;LLVM_ROOT=/path;...')
|
196
|
+
if not '=' in EM_CONFIG:
|
197
|
+
raise Exception('File ' + EM_CONFIG + ' passed to --em-config does not exist!')
|
198
|
+
else:
|
199
|
+
EM_CONFIG = EM_CONFIG.replace(';', '\n') + '\n'
|
200
|
+
|
193
201
|
if not EM_CONFIG:
|
194
202
|
EM_CONFIG = '~/.emscripten'
|
195
203
|
if '\n' in EM_CONFIG:
|
@@ -284,7 +292,7 @@ def check_node_version():
|
|
284
292
|
try:
|
285
293
|
node = listify(NODE_JS)
|
286
294
|
actual = Popen(node + ['--version'], stdout=PIPE).communicate()[0].strip()
|
287
|
-
version = tuple(map(int, actual.replace('v', '').split('.')))
|
295
|
+
version = tuple(map(int, actual.replace('v', '').replace('-pre', '').split('.')))
|
288
296
|
if version >= EXPECTED_NODE_VERSION:
|
289
297
|
return True
|
290
298
|
logging.warning('node version appears too old (seeing "%s", expected "%s")' % (actual, 'v' + ('.'.join(map(str, EXPECTED_NODE_VERSION)))))
|
@@ -314,7 +322,7 @@ def find_temp_directory():
|
|
314
322
|
# we re-check sanity when the settings are changed)
|
315
323
|
# We also re-check sanity and clear the cache when the version changes
|
316
324
|
|
317
|
-
EMSCRIPTEN_VERSION = '1.
|
325
|
+
EMSCRIPTEN_VERSION = '1.7.8'
|
318
326
|
|
319
327
|
def generate_sanity():
|
320
328
|
return EMSCRIPTEN_VERSION + '|' + get_llvm_target() + '|' + LLVM_ROOT
|
@@ -323,7 +331,7 @@ def check_sanity(force=False):
|
|
323
331
|
try:
|
324
332
|
reason = None
|
325
333
|
if not CONFIG_FILE:
|
326
|
-
|
334
|
+
return # config stored directly in EM_CONFIG => skip sanity checks
|
327
335
|
else:
|
328
336
|
settings_mtime = os.stat(CONFIG_FILE).st_mtime
|
329
337
|
sanity_file = CONFIG_FILE + '_sanity'
|
@@ -463,6 +471,18 @@ FILE_PACKAGER = path_from_root('tools', 'file_packager.py')
|
|
463
471
|
|
464
472
|
# Temp dir. Create a random one, unless EMCC_DEBUG is set, in which case use TEMP_DIR/emscripten_temp
|
465
473
|
|
474
|
+
def safe_ensure_dirs(dirname):
|
475
|
+
try:
|
476
|
+
os.makedirs(dirname)
|
477
|
+
except os.error, e:
|
478
|
+
# Ignore error for already existing dirname
|
479
|
+
if e.errno != errno.EEXIST:
|
480
|
+
raise e
|
481
|
+
# FIXME: Notice that this will result in a false positive,
|
482
|
+
# should the dirname be a file! There seems to no way to
|
483
|
+
# handle this atomically in Python 2.x.
|
484
|
+
# There is an additional option for Python 3.x, though.
|
485
|
+
|
466
486
|
class Configuration:
|
467
487
|
def __init__(self, environ=os.environ):
|
468
488
|
self.DEBUG = environ.get('EMCC_DEBUG')
|
@@ -487,10 +507,9 @@ class Configuration:
|
|
487
507
|
if self.DEBUG:
|
488
508
|
try:
|
489
509
|
self.EMSCRIPTEN_TEMP_DIR = self.CANONICAL_TEMP_DIR
|
490
|
-
|
491
|
-
os.makedirs(self.EMSCRIPTEN_TEMP_DIR)
|
510
|
+
safe_ensure_dirs(self.EMSCRIPTEN_TEMP_DIR)
|
492
511
|
except Exception, e:
|
493
|
-
logging.
|
512
|
+
logging.error(str(e) + 'Could not create canonical temp dir. Check definition of TEMP_DIR in ~/.emscripten')
|
494
513
|
|
495
514
|
def get_temp_files(self):
|
496
515
|
return tempfiles.TempFiles(
|
@@ -633,7 +652,7 @@ def check_engine(engine):
|
|
633
652
|
try:
|
634
653
|
if not CONFIG_FILE:
|
635
654
|
return True # config stored directly in EM_CONFIG => skip engine check
|
636
|
-
return 'hello, world!' in run_js(path_from_root('
|
655
|
+
return 'hello, world!' in run_js(path_from_root('src', 'hello_world.js'), engine)
|
637
656
|
except Exception, e:
|
638
657
|
print 'Checking JS engine %s failed. Check %s. Details: %s' % (str(engine), EM_CONFIG, str(e))
|
639
658
|
return False
|
@@ -922,7 +941,7 @@ class Building:
|
|
922
941
|
|
923
942
|
|
924
943
|
@staticmethod
|
925
|
-
def build_library(name, build_dir, output_dir, generated_libs, configure=['sh', './configure'], configure_args=[], make=['make'], make_args=
|
944
|
+
def build_library(name, build_dir, output_dir, generated_libs, configure=['sh', './configure'], configure_args=[], make=['make'], make_args='help', cache=None, cache_name=None, copy_project=False, env_init={}, source_dir=None, native=False):
|
926
945
|
''' Build a library into a .bc file. We build the .bc file once and cache it for all our tests. (We cache in
|
927
946
|
memory since the test directory is destroyed and recreated for each test. Note that we cache separately
|
928
947
|
for different compilers).
|
@@ -930,6 +949,8 @@ class Building:
|
|
930
949
|
|
931
950
|
if type(generated_libs) is not list: generated_libs = [generated_libs]
|
932
951
|
if source_dir is None: source_dir = path_from_root('tests', name.replace('_native', ''))
|
952
|
+
if make_args == 'help':
|
953
|
+
make_args = ['-j', str(multiprocessing.cpu_count())]
|
933
954
|
|
934
955
|
temp_dir = build_dir
|
935
956
|
if copy_project:
|
@@ -1024,8 +1045,7 @@ class Building:
|
|
1024
1045
|
try:
|
1025
1046
|
temp_dir = os.path.join(EMSCRIPTEN_TEMP_DIR, 'ar_output_' + str(os.getpid()) + '_' + str(len(temp_dirs)))
|
1026
1047
|
temp_dirs.append(temp_dir)
|
1027
|
-
|
1028
|
-
os.makedirs(temp_dir)
|
1048
|
+
safe_ensure_dirs(temp_dir)
|
1029
1049
|
os.chdir(temp_dir)
|
1030
1050
|
contents = filter(lambda x: len(x) > 0, Popen([LLVM_AR, 't', f], stdout=PIPE).communicate()[0].split('\n'))
|
1031
1051
|
#print >> sys.stderr, ' considering archive', f, ':', contents
|
@@ -1034,9 +1054,9 @@ class Building:
|
|
1034
1054
|
else:
|
1035
1055
|
for content in contents: # ar will silently fail if the directory for the file does not exist, so make all the necessary directories
|
1036
1056
|
dirname = os.path.dirname(content)
|
1037
|
-
if dirname
|
1038
|
-
|
1039
|
-
Popen([LLVM_AR, '
|
1057
|
+
if dirname:
|
1058
|
+
safe_ensure_dirs(dirname)
|
1059
|
+
Popen([LLVM_AR, 'xo', f], stdout=PIPE).communicate() # if absolute paths, files will appear there. otherwise, in this directory
|
1040
1060
|
contents = map(lambda content: os.path.join(temp_dir, content), contents)
|
1041
1061
|
contents = filter(os.path.exists, map(os.path.abspath, contents))
|
1042
1062
|
added_contents = set()
|
@@ -1117,14 +1137,16 @@ class Building:
|
|
1117
1137
|
# @param opt Either an integer, in which case it is the optimization level (-O1, -O2, etc.), or a list of raw
|
1118
1138
|
# optimization passes passed to llvm opt
|
1119
1139
|
@staticmethod
|
1120
|
-
def llvm_opt(filename, opts):
|
1140
|
+
def llvm_opt(filename, opts, out=None):
|
1121
1141
|
if type(opts) is int:
|
1122
1142
|
opts = Building.pick_llvm_opts(opts)
|
1123
1143
|
#opts += ['-debug-pass=Arguments']
|
1124
1144
|
logging.debug('emcc: LLVM opts: ' + str(opts))
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1145
|
+
target = out or (filename + '.opt.bc')
|
1146
|
+
output = Popen([LLVM_OPT, filename] + opts + ['-o', target], stdout=PIPE).communicate()[0]
|
1147
|
+
assert os.path.exists(target), 'Failed to run llvm optimizations: ' + output
|
1148
|
+
if not out:
|
1149
|
+
shutil.move(filename + '.opt.bc', filename)
|
1128
1150
|
|
1129
1151
|
@staticmethod
|
1130
1152
|
def llvm_opts(filename): # deprecated version, only for test runner. TODO: remove
|
@@ -1214,7 +1236,13 @@ class Building:
|
|
1214
1236
|
# Run Emscripten
|
1215
1237
|
Settings.RELOOPER = Cache.get_path('relooper.js')
|
1216
1238
|
settings = Settings.serialize()
|
1217
|
-
|
1239
|
+
args = settings + extra_args
|
1240
|
+
if WINDOWS:
|
1241
|
+
args = ['@' + response_file.create_response_file(args, TEMP_DIR)]
|
1242
|
+
cmdline = [PYTHON, EMSCRIPTEN, filename + ('.o.ll' if append_ext else ''), '-o', filename + '.o.js'] + args
|
1243
|
+
if jsrun.TRACK_PROCESS_SPAWNS:
|
1244
|
+
logging.info('Executing emscripten.py compiler with cmdline "' + ' '.join(cmdline) + '"')
|
1245
|
+
compiler_output = jsrun.timeout_run(Popen(cmdline, stdout=PIPE), None, 'Compiling')
|
1218
1246
|
#print compiler_output
|
1219
1247
|
|
1220
1248
|
# Detect compilation crashes and errors
|
@@ -1410,6 +1438,10 @@ class Building:
|
|
1410
1438
|
@staticmethod
|
1411
1439
|
def ensure_relooper(relooper):
|
1412
1440
|
if os.path.exists(relooper): return
|
1441
|
+
if os.environ.get('EMCC_FAST_COMPILER'):
|
1442
|
+
logging.debug('not building relooper to js, using it in c++ backend')
|
1443
|
+
return
|
1444
|
+
|
1413
1445
|
Cache.ensure()
|
1414
1446
|
curr = os.getcwd()
|
1415
1447
|
try:
|
@@ -1508,7 +1540,29 @@ class JS:
|
|
1508
1540
|
|
1509
1541
|
@staticmethod
|
1510
1542
|
def to_nice_ident(ident): # limited version of the JS function toNiceIdent
|
1511
|
-
return ident.replace('%', '$').replace('@', '_')
|
1543
|
+
return ident.replace('%', '$').replace('@', '_').replace('.', '_')
|
1544
|
+
|
1545
|
+
@staticmethod
|
1546
|
+
def make_initializer(sig, settings=None):
|
1547
|
+
settings = settings or Settings
|
1548
|
+
if sig == 'i':
|
1549
|
+
return '0'
|
1550
|
+
elif sig == 'f' and settings.get('PRECISE_F32'):
|
1551
|
+
return 'Math_fround(0)'
|
1552
|
+
else:
|
1553
|
+
return '+0'
|
1554
|
+
|
1555
|
+
@staticmethod
|
1556
|
+
def make_coercion(value, sig, settings=None):
|
1557
|
+
settings = settings or Settings
|
1558
|
+
if sig == 'i':
|
1559
|
+
return value + '|0'
|
1560
|
+
elif sig == 'f' and settings.get('PRECISE_F32'):
|
1561
|
+
return 'Math_fround(' + value + ')'
|
1562
|
+
elif sig == 'd' or sig == 'f':
|
1563
|
+
return '+' + value
|
1564
|
+
else:
|
1565
|
+
return value
|
1512
1566
|
|
1513
1567
|
@staticmethod
|
1514
1568
|
def make_extcall(sig, named=True):
|
Binary file
|