aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc20
-rw-r--r--src/intertyper.js4
-rw-r--r--src/library.js4
-rw-r--r--tests/test_core.py38
-rw-r--r--tests/test_other.py37
-rw-r--r--tools/js_optimizer.py1
-rw-r--r--tools/shared.py4
7 files changed, 102 insertions, 6 deletions
diff --git a/emcc b/emcc
index 8d840074..a6bf9c6a 100755
--- a/emcc
+++ b/emcc
@@ -423,7 +423,17 @@ Options that are modified or new in %s include:
-v Turns on verbose output. This will pass
-v to Clang, and also enable EMCC_DEBUG
- to details emcc's operations
+ to details emcc's operations.
+
+ It will also run emscripten's internal sanity
+ checks, checking that things like the LLVM directory
+ path looks correct, etc. This works with or
+ without other arguments, so it can be useful to run
+
+ emcc -v
+
+ if you see odd errors, as it can help diagnose
+ things.
--clear-cache Manually clears the cache of compiled
emscripten system libraries (libc++,
@@ -528,8 +538,9 @@ There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR P
elif len(sys.argv) == 2 and sys.argv[1] == '-v': # -v with no inputs
print 'emcc (Emscripten GCC-like replacement + linker emulating GNU ld ) %s' % shared.EMSCRIPTEN_VERSION
+ code = subprocess.call([shared.CLANG, '-v'])
shared.check_sanity(force=True)
- exit(subprocess.call([shared.CLANG, '-v']))
+ exit(code)
def is_minus_s_for_emcc(newargs, i):
assert newargs[i] == '-s'
@@ -1180,7 +1191,10 @@ try:
logging.warning('jcache is deprecated and not supported in fastcomp (you should not need it anyhow), disabling')
jcache = False
- fastcomp_opts = ['-pnacl-abi-simplify-preopt', '-pnacl-abi-simplify-postopt']
+ fastcomp_opts = []
+ if shared.Settings.NO_EXIT_RUNTIME:
+ fastcomp_opts += ['-emscripten-no-exit-runtime', '-globaldce']
+ fastcomp_opts += ['-pnacl-abi-simplify-preopt', '-pnacl-abi-simplify-postopt']
if shared.Settings.DISABLE_EXCEPTION_CATCHING != 1:
fastcomp_opts += ['-enable-emscripten-cxx-exceptions']
if len(shared.Settings.EXCEPTION_CATCHING_WHITELIST) > 0:
diff --git a/src/intertyper.js b/src/intertyper.js
index 7743ce62..323787ac 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -350,7 +350,9 @@ function intertyper(lines, sidePass, baseLineNums) {
triple = triple.substr(1, triple.length-2);
var expected = TARGET_ASMJS_UNKNOWN_EMSCRIPTEN ? 'asmjs-unknown-emscripten' : 'i386-pc-linux-gnu';
if (triple !== expected) {
- warn('using an unexpected LLVM triple: ' + [triple, ' !== ', expected] + ' (are you using emcc for everything and not clang?)');
+ if (!(TARGET_ASMJS_UNKNOWN_EMSCRIPTEN && triple === 'le32-unknown-nacl')) {
+ warn('using an unexpected LLVM triple: ' + [triple, ' !== ', expected] + ' (are you using emcc for everything and not clang?)');
+ }
}
}
return null;
diff --git a/src/library.js b/src/library.js
index 18a794fd..cd451c57 100644
--- a/src/library.js
+++ b/src/library.js
@@ -2420,7 +2420,9 @@ LibraryManager.library = {
fileno: function(stream) {
// int fileno(FILE *stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
- return FS.getStreamFromPtr(stream).fd;
+ stream = FS.getStreamFromPtr(stream);
+ if (!stream) return -1;
+ return stream.fd;
},
ftrylockfile: function() {
// int ftrylockfile(FILE *file);
diff --git a/tests/test_core.py b/tests/test_core.py
index 015f65bf..26bb71ef 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -507,6 +507,7 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
def test_asmjs_unknown_emscripten(self):
if self.emcc_args == None: return self.skip('needs emcc')
if not self.is_emscripten_abi(): return self.skip('asmjs-unknown-emscripten needed for asmjs-unknown-emscripten target test')
+ if os.environ.get('EMCC_FAST_COMPILER') == '0': return self.skip('fastcomp needed for asmjs-unknonw-emscripten target')
self.do_run(open(path_from_root('tests', 'asmjs-unknown-emscripten.c')).read(), '')
def test_cube2md5(self):
@@ -4066,6 +4067,28 @@ def process(filename):
self.emcc_args += ['--embed-file', 'three_numbers.txt']
self.do_run(src, 'match = 3\nx = -1.0, y = 0.1, z = -0.1\n')
+ def test_fileno(self):
+ if self.emcc_args is None: return self.skip('requires emcc')
+ open(os.path.join(self.get_dir(), 'empty.txt'), 'w').write('')
+ src = r'''
+ #include <stdio.h>
+ #include <unistd.h>
+ int main()
+ {
+ FILE* fp = fopen("empty.txt", "r");
+ if (fp) {
+ printf("%d\n", fp);
+ printf("%d\n", fileno(fp));
+ printf("%d\n", fileno((FILE*)42)); // nonexistent stream
+ } else {
+ printf("failed to open empty.txt\n");
+ }
+ return 0;
+ }
+ '''
+ self.emcc_args += ['--embed-file', 'empty.txt']
+ self.do_run(src, '4\n3\n-1\n')
+
def test_readdir(self):
src = open(path_from_root('tests', 'dirent', 'test_readdir.c'), 'r').read()
self.do_run(src, 'success', force_c=True)
@@ -4520,10 +4543,20 @@ PORT: 3979
### 'Medium' tests
def test_fannkuch(self):
+ try:
+ if self.run_name == 'slow2' or self.run_name == 'slow2asm':
+ old_target = os.environ.get('EMCC_LLVM_TARGET') or ''
+ os.environ['EMCC_LLVM_TARGET'] = "asmjs-unknown-emscripten" # testing for asm-emscripten target on non-fastcomp
results = [ (1,0), (2,1), (3,2), (4,4), (5,7), (6,10), (7, 16), (8,22) ]
for i, j in results:
src = open(path_from_root('tests', 'fannkuch.cpp'), 'r').read()
self.do_run(src, 'Pfannkuchen(%d) = %d.' % (i,j), [str(i)], no_build=i>1)
+ finally:
+ if self.run_name == 'slow2' or self.run_name == 'slow2asm':
+ if old_target:
+ os.environ['EMCC_LLVM_TARGET'] = old_target
+ else:
+ del os.environ['EMCC_LLVM_TARGET']
def test_raytrace(self):
if self.emcc_args is None: return self.skip('requires emcc')
@@ -5181,7 +5214,10 @@ def process(filename):
for name in glob.glob(path_from_root('tests', 'fuzz', '*.c')) + glob.glob(path_from_root('tests', 'fuzz', '*.cpp')):
#if os.path.basename(name) != '4.c': continue
if 'newfail' in name: continue
- if os.path.basename(name) == '18.cpp' and not os.environ.get('EMCC_FAST_COMPILER') != '0': continue # works only in fastcomp
+ if os.environ.get('EMCC_FAST_COMPILER') == '0' and os.path.basename(name) in [
+ '18.cpp', '15.c'
+ ]:
+ continue # works only in fastcomp
print name
self.do_run(open(path_from_root('tests', 'fuzz', name)).read(),
diff --git a/tests/test_other.py b/tests/test_other.py
index 55cc5635..f5a4ebc9 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -2391,3 +2391,40 @@ int main() {
assert 'emcc: warning: unaligned store' in output[1]
assert '@line 9 "src.cpp"' in output[1]
+ def test_no_exit_runtime(self):
+ open('code.cpp', 'w').write(r'''
+#include <stdio.h>
+
+template<int x>
+struct Waste {
+ Waste() {
+ printf("coming around %d\n", x);
+ }
+ ~Waste() {
+ printf("going away %d\n", x);
+ }
+};
+
+Waste<1> w1;
+Waste<2> w2;
+Waste<3> w3;
+Waste<4> w4;
+Waste<5> w5;
+
+int main(int argc, char **argv) {
+ return 0;
+}
+''')
+
+ for no_exit in [0, 1]:
+ for opts in [0, 1]:
+ print no_exit, opts
+ Popen([PYTHON, EMCC, '-O' + str(opts), 'code.cpp', '-s', 'NO_EXIT_RUNTIME=' + str(no_exit)]).communicate()
+ output = run_js(os.path.join(self.get_dir(), 'a.out.js'), stderr=PIPE, full_output=True, engine=NODE_JS)
+ src = open('a.out.js').read()
+ exit = 1-no_exit
+ assert 'coming around' in output
+ assert ('going away' in output) == exit, 'destructors should not run if no exit'
+ assert ('_ZN5WasteILi2EED1Ev' in src) == exit, 'destructors should not appear if no exit'
+ assert ('atexit(' in src) == exit, 'atexit should not appear or be called'
+
diff --git a/tools/js_optimizer.py b/tools/js_optimizer.py
index 9ba6643b..d6c705cd 100644
--- a/tools/js_optimizer.py
+++ b/tools/js_optimizer.py
@@ -212,6 +212,7 @@ EMSCRIPTEN_FUNCS();
chunk_size = min(MAX_CHUNK_SIZE, max(MIN_CHUNK_SIZE, total_size / intended_num_chunks))
chunks = shared.chunkify(funcs, chunk_size, jcache.get_cachename('jsopt') if jcache else None)
+ if DEBUG and len(chunks) > 0: print >> sys.stderr, 'chunkification: intended size:', chunk_size, 'num funcs:', len(funcs), 'actual num chunks:', len(chunks), 'chunk size range:', max(map(len, chunks)), '-', min(map(len, chunks))
funcs = None
if jcache:
diff --git a/tools/shared.py b/tools/shared.py
index a413a932..f2f90398 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -618,6 +618,10 @@ except:
# Target choice. Must be synced with src/settings.js (TARGET_*)
def get_llvm_target():
+ if os.environ.get('EMCC_FAST_COMPILER') == '0':
+ if not os.environ.get('EMCC_LLVM_TARGET'):
+ os.environ['EMCC_LLVM_TARGET'] = 'le32-unknown-nacl'
+ return os.environ.get('EMCC_LLVM_TARGET')
return os.environ.get('EMCC_LLVM_TARGET') or 'asmjs-unknown-emscripten'
LLVM_TARGET = get_llvm_target()