aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/js-optimizer.js25
-rw-r--r--tools/shared.py46
-rwxr-xr-xtools/source-maps/sourcemapper.js2
-rw-r--r--tools/test-js-optimizer-asm-last-output.js28
-rw-r--r--tools/test-js-optimizer-asm-last.js34
-rw-r--r--tools/test-js-optimizer-asm-pre-output.js1
-rw-r--r--tools/test-js-optimizer-asm-pre.js1
7 files changed, 108 insertions, 29 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 151e573a..d04807a7 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -188,12 +188,12 @@ function traverseChildren(node, traverse, pre, post, stack) {
// was stopped, true. Otherwise undefined.
function traverse(node, pre, post, stack) {
var type = node[0], result, len;
- var relevant = typeof node[0] === 'string';
+ var relevant = typeof type === 'string';
if (relevant) {
if (stack) len = stack.length;
var result = pre(node, type, stack);
if (result === true) return true;
- if (Array.isArray(result)) node = result; // Continue processing on this node
+ if (result && result !== null) node = result; // Continue processing on this node
if (stack && len === stack.length) stack.push(0);
}
if (result !== null) {
@@ -584,6 +584,8 @@ function simplifyExpressionsPre(ast) {
node[3] = value[2];
}
}
+ } else if (type == 'sub' && node[1][0] == 'name' && /^FUNCTION_TABLE.*/.exec(node[1][1])) {
+ return null; // do not traverse subchildren here, we should not collapse 55 & 126. TODO: optimize this into a nonvirtual call (also because we lose some other opts here)!
}
});
@@ -2035,7 +2037,6 @@ function eliminate(ast, memSafe) {
// examine body and note locals
var hasSwitch = false;
traverse(func, function(node, type) {
- if (debug && type) type = type.toString();
if (type === 'var') {
var node1 = node[1];
for (var i = 0; i < node1.length; i++) {
@@ -2645,7 +2646,6 @@ function eliminate(ast, memSafe) {
var has_num = false;
var fail = false;
traverse(node, function(subNode, subType) {
- if (debug && subType) subType = subType.toString();
if (subType === 'binary') {
if (subNode[1] !== '+') {
fail = true;
@@ -2807,6 +2807,23 @@ function asmLoopOptimizer(ast) {
var stats = node[2][1];
var last = stats[stats.length-1];
if (last && last[0] === 'if' && !last[3] && last[2][0] === 'block' && last[2][1][0] && last[2][1][0][0] === 'break' && !last[2][1][0][1]) {
+ var abort = false;
+ var stack = 0;
+ traverse(stats, function(node, type) {
+ if (type == 'continue') {
+ if (stack == 0 || node[1]) { // abort if labeled (we do not analyze labels here yet), or a continue directly on us
+ abort = true;
+ return true;
+ }
+ } else if (type in LOOP) {
+ stack++;
+ }
+ }, function(node, type) {
+ if (type in LOOP) {
+ stack--;
+ }
+ });
+ if (abort) return;
var conditionToBreak = last[1];
stats.pop();
node[0] = 'do';
diff --git a/tools/shared.py b/tools/shared.py
index 2a754d27..776001cd 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -1,6 +1,7 @@
import shutil, time, os, sys, json, tempfile, copy, shlex, atexit, subprocess, hashlib, cPickle, re
from subprocess import Popen, PIPE, STDOUT
from tempfile import mkstemp
+from distutils.spawn import find_executable
import jsrun, cache, tempfiles
from response_file import create_response_file
import logging, platform
@@ -204,25 +205,12 @@ else:
config_file = '\n'.join(config_file)
# autodetect some default paths
config_file = config_file.replace('{{{ EMSCRIPTEN_ROOT }}}', __rootpath__)
- llvm_root = '/usr/bin'
- try:
- llvm_root = os.path.dirname(Popen(['which', 'llvm-dis'], stdout=PIPE).communicate()[0].replace('\n', ''))
- except:
- pass
+ llvm_root = find_executable('llvm-dis') or '/usr/bin'
config_file = config_file.replace('{{{ LLVM_ROOT }}}', llvm_root)
- node = 'node'
- try:
- node = Popen(['which', 'node'], stdout=PIPE).communicate()[0].replace('\n', '') or \
- Popen(['which', 'nodejs'], stdout=PIPE).communicate()[0].replace('\n', '') or node
- except:
- pass
+ node = find_executable('node') or find_executable('nodejs') or 'node'
config_file = config_file.replace('{{{ NODE }}}', node)
- python = sys.executable or 'python'
- try:
- python = Popen(['which', 'python2'], stdout=PIPE).communicate()[0].replace('\n', '') or \
- Popen(['which', 'python'], stdout=PIPE).communicate()[0].replace('\n', '') or python
- except:
- pass
+ python = find_executable('python2') or find_executable('python') or \
+ sys.executable or 'python'
config_file = config_file.replace('{{{ PYTHON }}}', python)
# write
@@ -295,7 +283,7 @@ def check_node_version():
# we re-check sanity when the settings are changed)
# We also re-check sanity and clear the cache when the version changes
-EMSCRIPTEN_VERSION = '1.5.1'
+EMSCRIPTEN_VERSION = '1.5.3'
def generate_sanity():
return EMSCRIPTEN_VERSION + '|' + get_llvm_target()
@@ -324,6 +312,7 @@ def check_sanity(force=False):
if reason:
logging.warning('(Emscripten: %s, clearing cache)' % reason)
Cache.erase()
+ force = False # the check actually failed, so definitely write out the sanity file, to avoid others later seeing failures too
# some warning, not fatal checks - do them even if EM_IGNORE_SANITY is on
check_llvm_version()
@@ -944,7 +933,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
# Finish link
actual_files = unique_ordered(actual_files) # tolerate people trying to link a.so a.so etc.
- logging.debug('emcc: llvm-linking: %s', actual_files)
+ logging.debug('emcc: llvm-linking: %s to %s', actual_files, target)
# check for too-long command line
link_cmd = [LLVM_LINK] + actual_files + ['-o', target]
@@ -1111,7 +1100,9 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
@staticmethod
def get_safe_internalize():
- exports = ','.join(map(lambda exp: exp[1:], expand_response(Settings.EXPORTED_FUNCTIONS)))
+ exps = expand_response(Settings.EXPORTED_FUNCTIONS)
+ if '_malloc' not in exps: exps.append('_malloc') # needed internally, even if user did not add to EXPORTED_FUNCTIONS
+ exports = ','.join(map(lambda exp: exp[1:], exps))
# internalize carefully, llvm 3.2 will remove even main if not told not to
return ['-internalize', '-internalize-public-api-list=' + exports]
@@ -1293,9 +1284,6 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
emcc_debug = os.environ.get('EMCC_DEBUG')
if emcc_debug: del os.environ['EMCC_DEBUG']
- emcc_optimize_normally = os.environ.get('EMCC_OPTIMIZE_NORMALLY')
- if emcc_optimize_normally: del os.environ['EMCC_OPTIMIZE_NORMALLY']
-
def make(opt_level):
raw = relooper + '.raw.js'
Building.emcc(os.path.join('relooper', 'Relooper.cpp'), ['-I' + os.path.join('relooper'), '--post-js',
@@ -1326,7 +1314,6 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
finally:
os.chdir(curr)
if emcc_debug: os.environ['EMCC_DEBUG'] = emcc_debug
- if emcc_optimize_normally: os.environ['EMCC_OPTIMIZE_NORMALLY'] = emcc_optimize_normally
if not ok:
logging.error('bootstrapping relooper failed. You may need to manually create relooper.js by compiling it, see src/relooper/emscripten')
1/0
@@ -1392,6 +1379,17 @@ def execute(cmd, *args, **kw):
logging.error('Invoking Process failed: <<< ' + cmd + ' >>>')
raise
+def check_execute(cmd, *args, **kw):
+ # TODO: use in more places. execute doesn't actually check that return values
+ # are nonzero
+ try:
+ kw['stderr'] = STDOUT
+ subprocess.check_output(cmd, *args, **kw)
+ logging.debug("Successfuly executed %s" % " ".join(cmd))
+ except subprocess.CalledProcessError as e:
+ logging.error("'%s' failed with output:\n%s" % (" ".join(e.cmd), e.output))
+ raise
+
def suffix(name):
parts = name.split('.')
if len(parts) > 1:
diff --git a/tools/source-maps/sourcemapper.js b/tools/source-maps/sourcemapper.js
index 0001e7c7..fa908900 100755
--- a/tools/source-maps/sourcemapper.js
+++ b/tools/source-maps/sourcemapper.js
@@ -110,7 +110,7 @@ function generateMap(mappings, sourceRoot, mapFileBaseName, generatedLineOffset)
try {
generator.setSourceContent(originalFileName, fs.readFileSync(rootedPath, 'utf-8'));
} catch (e) {
- console.warn("Unable to find original file for " + originalFileName +
+ console.warn("sourcemapper: Unable to find original file for " + originalFileName +
" at " + rootedPath);
}
}
diff --git a/tools/test-js-optimizer-asm-last-output.js b/tools/test-js-optimizer-asm-last-output.js
index cbc0a4d3..0f95d544 100644
--- a/tools/test-js-optimizer-asm-last-output.js
+++ b/tools/test-js-optimizer-asm-last-output.js
@@ -42,5 +42,33 @@ function looop() {
do {
do_it();
} while (x());
+ while (1) {
+ do_it();
+ if (a()) continue;
+ if (!x()) {
+ break;
+ }
+ }
+ do {
+ do_it();
+ do {
+ if (a()) continue;
+ } while (b());
+ } while (x());
+ do {
+ do_it();
+ while (b()) {
+ if (a()) continue;
+ }
+ } while (x());
+ X : while (1) {
+ do_it();
+ while (b()) {
+ if (a()) continue X;
+ }
+ if (!x()) {
+ break;
+ }
+ }
}
diff --git a/tools/test-js-optimizer-asm-last.js b/tools/test-js-optimizer-asm-last.js
index 6331879e..05e1049e 100644
--- a/tools/test-js-optimizer-asm-last.js
+++ b/tools/test-js-optimizer-asm-last.js
@@ -51,6 +51,40 @@ function looop() {
break;
}
}
+ while (1) {
+ do_it();
+ if (a()) continue; // we cannot move to do-while, continue will hit the while check
+ if (!x()) {
+ break;
+ }
+ }
+ while (1) {
+ do_it();
+ do {
+ if (a()) continue; // ok to optimize, continue is not for us
+ } while (b());
+ if (!x()) {
+ break;
+ }
+ }
+ while (1) {
+ do_it();
+ while (b()) {
+ if (a()) continue; // also ok to optimize, continue is not for us
+ }
+ if (!x()) {
+ break;
+ }
+ }
+ X: while (1) {
+ do_it();
+ while (b()) {
+ if (a()) continue X; // not ok to optimize
+ }
+ if (!x()) {
+ break;
+ }
+ }
}
// EMSCRIPTEN_GENERATED_FUNCTIONS: ["finall", "looop"]
diff --git a/tools/test-js-optimizer-asm-pre-output.js b/tools/test-js-optimizer-asm-pre-output.js
index 2cd8d407..301a2ec8 100644
--- a/tools/test-js-optimizer-asm-pre-output.js
+++ b/tools/test-js-optimizer-asm-pre-output.js
@@ -19,6 +19,7 @@ function a() {
f(g() | 0 & -1);
f((g() | 0) >> 2);
$56 = _fcntl() | 0 | 1;
+ FUNCTION_TABLE_ii[55 & 127]() | 0;
}
function b($this, $__n) {
$this = $this | 0;
diff --git a/tools/test-js-optimizer-asm-pre.js b/tools/test-js-optimizer-asm-pre.js
index ca7d2894..c7c92124 100644
--- a/tools/test-js-optimizer-asm-pre.js
+++ b/tools/test-js-optimizer-asm-pre.js
@@ -20,6 +20,7 @@ function a() {
f(g() | 0 & -1);
f((g() | 0) >> 2);
$56 = (_fcntl() | 0) | 1;
+ FUNCTION_TABLE_ii[55 & 127]() | 0;
}
function b($this, $__n) {
$this = $this | 0;