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
@@ -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
|