aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/aniso.c5
-rw-r--r--tests/cases/longjmp_tiny_invoke_phi.ll46
-rw-r--r--tests/cases/longjmp_tiny_invoke_phi.txt4
-rw-r--r--tests/core/closebitcasts.c32
-rw-r--r--tests/core/closebitcasts.txt2
-rw-r--r--tests/cubegeom.c12
-rwxr-xr-xtests/fuzz/test.sh52
-rwxr-xr-xtests/runner.py1
-rw-r--r--tests/sdl_canvas.c2
-rw-r--r--tests/test_benchmark.py6
-rw-r--r--tests/test_browser.py21
-rw-r--r--tests/test_core.py13
-rw-r--r--tests/test_other.py127
-rw-r--r--tests/test_sanity.py28
14 files changed, 269 insertions, 82 deletions
diff --git a/tests/aniso.c b/tests/aniso.c
index f1674cad..443e50aa 100644
--- a/tests/aniso.c
+++ b/tests/aniso.c
@@ -151,6 +151,11 @@ int main(int argc, char *argv[])
assert(!glGetError());
glBindFramebuffer(GL_RENDERBUFFER, 0);
assert(glGetError());
+
+ GLint out = 321;
+ assert(!glGetError());
+ glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &out); // invalid, just test output
+ assert(out == 0);
}
// Prepare and Render
diff --git a/tests/cases/longjmp_tiny_invoke_phi.ll b/tests/cases/longjmp_tiny_invoke_phi.ll
new file mode 100644
index 00000000..30c43339
--- /dev/null
+++ b/tests/cases/longjmp_tiny_invoke_phi.ll
@@ -0,0 +1,46 @@
+; ModuleID = '/tmp/emscripten_temp/src.cpp.o'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
+target triple = "i386-pc-linux-gnu"
+
+@_ZL3buf = internal global [20 x i16] zeroinitializer, align 2
+@.str = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1
+@.str1 = private unnamed_addr constant [6 x i8] c"more\0A\00", align 1
+@.str2 = private unnamed_addr constant [6 x i8] c"fair\0A\00", align 1
+
+define i32 @main() {
+entry:
+ %retval = alloca i32, align 4
+ store i32 0, i32* %retval
+ %call = invoke i32 @setjmp(i16* getelementptr inbounds ([20 x i16]* @_ZL3buf, i32 0, i32 0)) returns_twice
+ to label %allgood unwind label %awful
+
+allgood:
+ %p = phi i32 [0, %entry], [1, %if.else]
+ %calll = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str2, i32 0, i32 0))
+ %total = add i32 %p, %call
+ %tobool = icmp ne i32 %total, 10
+ br i1 %tobool, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @.str, i32 0, i32 0))
+ call void @longjmp(i16* getelementptr inbounds ([20 x i16]* @_ZL3buf, i32 0, i32 0), i32 10)
+ br label %if.end
+
+if.else: ; preds = %entry
+ %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0))
+ %chak = icmp ne i32 %call2, 1337
+ br i1 %chak, label %if.end, label %allgood
+
+if.end: ; preds = %if.else, %if.then
+ ret i32 0
+
+awful:
+ ret i32 1
+}
+
+declare i32 @setjmp(i16*) returns_twice
+
+declare i32 @printf(i8*, ...)
+
+declare void @longjmp(i16*, i32)
+
diff --git a/tests/cases/longjmp_tiny_invoke_phi.txt b/tests/cases/longjmp_tiny_invoke_phi.txt
new file mode 100644
index 00000000..aaa41d11
--- /dev/null
+++ b/tests/cases/longjmp_tiny_invoke_phi.txt
@@ -0,0 +1,4 @@
+fair
+hello world
+fair
+more
diff --git a/tests/core/closebitcasts.c b/tests/core/closebitcasts.c
new file mode 100644
index 00000000..2c9d5ab5
--- /dev/null
+++ b/tests/core/closebitcasts.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+ float x = argc%17, y = (argc+1)*(argc+2)*(argc+3)*(argc+4)*(argc*5);
+ y *= 1<<30;
+ y *= -13;
+ if (argc == 17) { x++; y--; }
+ int *xi = (int*)&x;
+ int *yi = (int*)&y;
+ int z = *xi - *yi;
+ while (z % 15) {
+ z++;
+ }
+ printf("!%d\n", z);
+
+ double xd = x, yd = y;
+ yd = yd*yd;
+ yd = yd*yd;
+ int *xl = (int*)&xd;
+ int *xh = &((int*)&xd)[1];
+ int *yl = (int*)&yd;
+ int *yh = &((int*)&yd)[1];
+ int l = *xl - *yl;
+ int h = *xh - *yh;
+ while (l % 15) {
+ l++;
+ h += 3;
+ }
+ printf("%d,%d!\n", l, h);
+ return 0;
+}
+
diff --git a/tests/core/closebitcasts.txt b/tests/core/closebitcasts.txt
new file mode 100644
index 00000000..f97366cd
--- /dev/null
+++ b/tests/core/closebitcasts.txt
@@ -0,0 +1,2 @@
+!1787576325
+589815810,-179981561!
diff --git a/tests/cubegeom.c b/tests/cubegeom.c
index 96d56339..e749045b 100644
--- a/tests/cubegeom.c
+++ b/tests/cubegeom.c
@@ -54,9 +54,21 @@ int main(int argc, char *argv[])
// Create a texture
+ GLuint boundTex = 123;
+ assert(!glGetError());
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTex);
+ assert(!glGetError());
+ assert(boundTex == 0);
+
GLuint texture;
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
+
+ assert(!glGetError());
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTex);
+ assert(!glGetError());
+ assert(boundTex == texture);
+
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
GLubyte textureData[16*16*4];
diff --git a/tests/fuzz/test.sh b/tests/fuzz/test.sh
index cc77dba4..166d4bab 100755
--- a/tests/fuzz/test.sh
+++ b/tests/fuzz/test.sh
@@ -2,22 +2,38 @@
# ~/Dev/emscripten/tests/fuzz$ CSMITH=~/Dev/csmith/src/csmith CSMITH_PATH=~/Dev/csmith python ./csmith_driver.py
# to find failures, then check those out with this script
-echo "0"
-gcc $1 -I/home/alon/Dev/csmith/runtime &> /dev/null
-~/Dev/emscripten/emcc $1 -I/home/alon/Dev/csmith/runtime &> /dev/null
-./a.out > o
-mozjs a.out.js > b
-diff o b
-echo "1"
-gcc -O1 $1 -I/home/alon/Dev/csmith/runtime &> /dev/null
-~/Dev/emscripten/emcc -O1 $1 -I/home/alon/Dev/csmith/runtime &> /dev/null
-./a.out > o
-mozjs a.out.js > b
-diff o b
-echo "2"
-gcc -O2 $1 -I/home/alon/Dev/csmith/runtime &> /dev/null
-~/Dev/emscripten/emcc -O2 $1 -I/home/alon/Dev/csmith/runtime &> /dev/null
-./a.out > o
-mozjs a.out.js > b
-diff o b
+echo "builds"
+gcc $@ -I/home/alon/Dev/csmith/runtime -o n1.out &> /dev/null
+/home/alon/Dev/fastcomp/build/Release/bin/clang $@ -I/home/alon/Dev/csmith/runtime -o n2.out &> /dev/null
+/home/alon/Dev/fastcomp/build/Release/bin/clang $@ -I/home/alon/Dev/csmith/runtime -emit-llvm -c -o bc.bc &> o
+~/Dev/emscripten/emcc $@ -I/home/alon/Dev/csmith/runtime -o js.out.js &> /dev/null
+#~/Dev/emscripten/emcc $@ -s UNALIGNED_MEMORY=1 -I/home/alon/Dev/csmith/runtime -o ua.out.js &> /dev/null
+#~/Dev/emscripten/emcc $@ -s SAFE_HEAP=1 -I/home/alon/Dev/csmith/runtime -o sh.out.js &> /dev/null
+EMCC_FAST_COMPILER=1 ~/Dev/emscripten/emcc $@ -I/home/alon/Dev/csmith/runtime -o fc.out.js &> /dev/null
+echo "run n1"
+./n1.out &> n1
+echo "run n2"
+./n2.out &> n2
+echo "run bc"
+/home/alon/Dev/fastcomp/build/Release/bin/lli bc.bc &> bc
+echo "run js"
+mozjs js.out.js &> js
+echo "run ua"
+#mozjs ua.out.js &> ua
+echo "run sh"
+#mozjs sh.out.js &> sh
+echo "run fc"
+mozjs fc.out.js &> fc
+echo "n/n"
+diff n1 n2
+echo "n/bc"
+diff n1 bc
+echo "n/js"
+diff n1 js | grep -v warning
+echo "n/js-ua"
+#diff n1 ua | grep -v warning
+echo "n/js-sh"
+#diff n1 sh | grep -v warning
+echo "js/js"
+diff js fc | grep -v warning
diff --git a/tests/runner.py b/tests/runner.py
index 37e307e9..72e940cb 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -649,6 +649,7 @@ class BrowserCore(RunnerCore):
def btest(self, filename, expected=None, reference=None, force_c=False, reference_slack=0, manual_reference=False, post_build=None,
args=[], outfile='test.html', message='.'): # TODO: use in all other tests
+ if os.environ.get('EMCC_FAST_COMPILER') == '1' and 'LEGACY_GL_EMULATION=1' in args: return self.skip('no legacy gl emulation in fastcomp')
# if we are provided the source and not a path, use that
filename_is_src = '\n' in filename
src = filename if filename_is_src else ''
diff --git a/tests/sdl_canvas.c b/tests/sdl_canvas.c
index 6bd659b8..cab48985 100644
--- a/tests/sdl_canvas.c
+++ b/tests/sdl_canvas.c
@@ -62,6 +62,8 @@ int main(int argc, char **argv) {
printf("you should see two lines of text in different colors and a blue rectangle\n");
+ SDL_UnlockSurface(screen);
+
SDL_Quit();
printf("done.\n");
diff --git a/tests/test_benchmark.py b/tests/test_benchmark.py
index 60670ed4..625340ea 100644
--- a/tests/test_benchmark.py
+++ b/tests/test_benchmark.py
@@ -58,7 +58,7 @@ class NativeBenchmarker(Benchmarker):
def build(self, parent, filename, args, shared_args, emcc_args, native_args, native_exec, lib_builder):
self.parent = parent
- if lib_builder: native_args += lib_builder(self.name, native=True, env_init={ 'CC': self.cc, 'CXX': self.cxx })
+ if lib_builder: native_args = native_args + lib_builder(self.name, native=True, env_init={ 'CC': self.cc, 'CXX': self.cxx })
if not native_exec:
compiler = self.cxx if filename.endswith('cpp') else self.cc
process = Popen([compiler, '-O2', '-fno-math-errno', filename, '-o', filename+'.native'] + shared_args + native_args, stdout=PIPE, stderr=parent.stderr_redirect)
@@ -90,7 +90,7 @@ class JSBenchmarker(Benchmarker):
def build(self, parent, filename, args, shared_args, emcc_args, native_args, native_exec, lib_builder):
self.filename = filename
- if lib_builder: emcc_args += lib_builder('js', native=False, env_init={})
+ if lib_builder: emcc_args = emcc_args + lib_builder('js', native=False, env_init={})
open('hardcode.py', 'w').write('''
def process(filename):
@@ -124,7 +124,7 @@ benchmarkers = [
#NativeBenchmarker('gcc', 'gcc', 'g++'),
#JSBenchmarker('sm-f32', SPIDERMONKEY_ENGINE, ['-s', 'PRECISE_F32=2']),
JSBenchmarker('sm', SPIDERMONKEY_ENGINE),
- JSBenchmarker('sm-fc', SPIDERMONKEY_ENGINE, env={ 'EMCC_FAST_COMPILER': '1' }),
+ #JSBenchmarker('sm-fc', SPIDERMONKEY_ENGINE, env={ 'EMCC_FAST_COMPILER': '1' }),
#JSBenchmarker('sm-noasm', SPIDERMONKEY_ENGINE + ['--no-asmjs']),
#JSBenchmarker('sm-noasm-f32', SPIDERMONKEY_ENGINE + ['--no-asmjs'], ['-s', 'PRECISE_F32=2']),
#JSBenchmarker('v8', V8_ENGINE)
diff --git a/tests/test_browser.py b/tests/test_browser.py
index 920c6f8c..20b38bb5 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -120,6 +120,8 @@ If manually bisecting:
'''
def test_emscripten_log(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('fastcomp uses asm, where call stacks are sometimes less clear')
+
src = os.path.join(self.get_dir(), 'src.cpp')
open(src, 'w').write(self.with_report_result(open(path_from_root('tests', 'emscripten_log', 'emscripten_log.cpp')).read()))
@@ -680,10 +682,7 @@ If manually bisecting:
self.btest('sdl_stb_image_data.c', reference='screenshot.jpg', args=['-s', 'STB_IMAGE=1', '--preload-file', 'screenshot.not'])
def test_sdl_canvas(self):
- open(os.path.join(self.get_dir(), 'sdl_canvas.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_canvas.c')).read()))
-
- Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_canvas.c'), '-o', 'page.html', '-s', 'LEGACY_GL_EMULATION=1']).communicate()
- self.run_browser('page.html', '', '/report_result?1')
+ self.btest('sdl_canvas.c', expected='1', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_sdl_canvas_proxy(self):
def post():
@@ -1111,6 +1110,8 @@ keydown(100);keyup(100); // trigger the end
self.run_browser('page.html', '', '/report_result?1')
def test_sdl_audio_beeps(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo c++ exceptions in fastcomp')
+
open(os.path.join(self.get_dir(), 'sdl_audio_beep.cpp'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_beep.cpp')).read()))
# use closure to check for a possible bug with closure minifying away newer Audio() attributes
@@ -1194,10 +1195,7 @@ keydown(100);keyup(100); // trigger the end
self.btest('openal_buffers.c', '0', args=['--preload-file', 'the_entertainer.wav'],)
def test_glfw(self):
- open(os.path.join(self.get_dir(), 'glfw.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'glfw.c')).read()))
-
- Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'glfw.c'), '-o', 'page.html', '-s', 'LEGACY_GL_EMULATION=1']).communicate()
- self.run_browser('page.html', '', '/report_result?1')
+ self.btest('glfw.c', '1', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_egl(self):
open(os.path.join(self.get_dir(), 'test_egl.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'test_egl.c')).read()))
@@ -1436,6 +1434,8 @@ keydown(100);keyup(100); // trigger the end
self.btest('sdl_resize.c', '1')
def test_gc(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('flaky in fastcomp and also non-fastcomp -O1, timing issues')
+
self.btest('browser_gc.cpp', '1')
def test_glshaderinfo(self):
@@ -1622,11 +1622,12 @@ keydown(100);keyup(100); // trigger the end
self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=11, args=['--pre-js', 'asset_a.js', '--pre-js', 'asset_b.js', '-s', 'LEGACY_GL_EMULATION=1'])
def test_aniso(self):
- if SPIDERMONKEY_ENGINE in JS_ENGINES:
+ if SPIDERMONKEY_ENGINE in JS_ENGINES and os.environ.get('EMCC_FAST_COMPILER') != '1':
# asm.js-ification check
Popen([PYTHON, EMCC, path_from_root('tests', 'aniso.c'), '-O2', '-g2', '-s', 'LEGACY_GL_EMULATION=1']).communicate()
Settings.ASM_JS = 1
self.run_generated_code(SPIDERMONKEY_ENGINE, 'a.out.js')
+ print 'passed asm test'
shutil.copyfile(path_from_root('tests', 'water.dds'), 'water.dds')
self.btest('aniso.c', reference='aniso.png', reference_slack=2, args=['--preload-file', 'water.dds', '-s', 'LEGACY_GL_EMULATION=1'])
@@ -1681,6 +1682,8 @@ keydown(100);keyup(100); // trigger the end
self.btest('http.cpp', expected='0', args=['-I' + path_from_root('tests')])
def test_module(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
Popen([PYTHON, EMCC, path_from_root('tests', 'browser_module.cpp'), '-o', 'module.js', '-O2', '-s', 'SIDE_MODULE=1', '-s', 'DLOPEN_SUPPORT=1', '-s', 'EXPORTED_FUNCTIONS=["_one", "_two"]']).communicate()
self.btest('browser_main.cpp', args=['-O2', '-s', 'MAIN_MODULE=1', '-s', 'DLOPEN_SUPPORT=1'], expected='8')
diff --git a/tests/test_core.py b/tests/test_core.py
index 2430aa1c..6442f894 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -771,6 +771,12 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
self.do_run_from_file(src, output)
+ def test_closebitcasts(self):
+ if Settings.USE_TYPED_ARRAYS != 2: return self.skip('requires ta2')
+ test_path = path_from_root('tests', 'core', 'closebitcasts')
+ src, output = (test_path + s for s in ('.c', '.txt'))
+ self.do_run_from_file(src, output)
+
def test_fast_math(self):
if self.emcc_args is None: return self.skip('requires emcc')
Building.COMPILER_TEST_OPTS += ['-ffast-math']
@@ -931,6 +937,8 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
for named in (0, 1):
print named
+ if os.environ.get('EMCC_FAST_COMPILER') == '1' and named: continue # no named globals in fastcomp
+
Settings.NAMED_GLOBALS = named
self.do_run_from_file(src, output, ['wowie', 'too', '74'])
@@ -5026,8 +5034,8 @@ def process(filename):
'structphiparam', 'callwithstructural_ta2', 'callwithstructural64_ta2', 'structinparam', # pnacl limitations in ExpandStructRegs
'2xi40', # pnacl limitations in ExpandGetElementPtr
'legalizer_ta2', '514_ta2', # pnacl limitation in not legalizing i104, i96, etc.
- 'longjmp_tiny', 'longjmp_tiny_invoke', 'longjmp_tiny_phi', 'longjmp_tiny_phi2', 'indirectbrphi', 'ptrtoint_blockaddr', 'quoted', # current fastcomp limitations FIXME
- 'sillyfuncast', 'sillyfuncast2', 'sillybitcast', # TODO very very soon XXX
+ 'longjmp_tiny', 'longjmp_tiny_invoke', 'longjmp_tiny_phi', 'longjmp_tiny_phi2', 'longjmp_tiny_invoke_phi', 'indirectbrphi', 'ptrtoint_blockaddr', 'quoted', # current fastcomp limitations FIXME
+ 'sillyfuncast', 'sillyfuncast2', 'sillybitcast', 'atomicrmw_unaligned' # TODO XXX
]: continue
if '_ta2' in shortname and not Settings.USE_TYPED_ARRAYS == 2:
print self.skip('case "%s" only relevant for ta2' % shortname)
@@ -6085,6 +6093,7 @@ def process(filename):
self.build(src, dirname, os.path.join(dirname, 'src.cpp'), post_build=(None, post))
def test_emscripten_log(self):
+ self.banned_js_engines = [SPIDERMONKEY_ENGINE] # XXX, emscripten_log is broken in spidermonkey currently, issue #1970
if self.emcc_args is None: return self.skip('This test needs libc.')
if '-g' not in Building.COMPILER_TEST_OPTS: Building.COMPILER_TEST_OPTS.append('-g')
self.do_run('#define RUN_FROM_JS_SHELL\n' + open(path_from_root('tests', 'emscripten_log', 'emscripten_log.cpp')).read(), "Success!")
diff --git a/tests/test_other.py b/tests/test_other.py
index a6e8b533..4bdd889b 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -397,6 +397,8 @@ f.close()
self.assertContained('hello, world!', run_js(os.path.join(self.get_dir(), 'a.out.js')))
def test_unaligned_memory(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
open(os.path.join(self.get_dir(), 'test.cpp'), 'w').write(r'''
#include <stdio.h>
#include <stdarg.h>
@@ -421,6 +423,8 @@ f.close()
self.assertContained('data: 67452301\ndata[0,1] 16bit: 2301\ndata[1,2] 16bit: 4523', run_js(os.path.join(self.get_dir(), 'a.out.js')))
def test_unaligned_memory_2(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
open(os.path.join(self.get_dir(), 'test.cpp'), 'w').write(r'''
#include <string>
#include <stdio.h>
@@ -463,6 +467,7 @@ f.close()
assert 'function _malloc' in src
def test_dangerous_func_cast(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
src = r'''
#include <stdio.h>
typedef void (*voidfunc)();
@@ -522,6 +527,8 @@ f.close()
assert not os.path.exists('a.out') and not os.path.exists('a.exe'), 'Must not leave unneeded linker stubs'
def test_static_link(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
def test(name, header, main, side, expected, args=[], suffix='cpp', first=True):
print name
#t = main ; main = side ; side = t
@@ -1165,7 +1172,7 @@ f.close()
''')
Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--js-library', os.path.join(self.get_dir(), 'mylib1.js'),
- '--js-library', os.path.join(self.get_dir(), 'mylib2.js')]).communicate()
+ '--js-library', os.path.join(self.get_dir(), 'mylib2.js')]).communicate()
self.assertContained('hello from lib!\n*32*\n', run_js(os.path.join(self.get_dir(), 'a.out.js')))
def test_identical_basenames(self):
@@ -1374,60 +1381,66 @@ f.close()
assert output == ''
def test_multidynamic_link(self):
- # Linking the same dynamic library in will error, normally, since we statically link it, causing dupe symbols
- # A workaround is to use --ignore-dynamic-linking, see emcc --help for details
+ # Linking the same dynamic library in statically will error, normally, since we statically link it, causing dupe symbols
- open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(r'''
- #include <stdio.h>
- extern void printey();
- extern void printother();
- int main() {
- printf("*");
- printey();
- printf("\n");
- printother();
- printf("\n");
- printf("*");
- return 0;
- }
- ''')
+ def test(link_cmd, lib_suffix=''):
+ print link_cmd, lib_suffix
- try:
- os.makedirs(os.path.join(self.get_dir(), 'libdir'));
- except:
- pass
+ self.clear()
- open(os.path.join(self.get_dir(), 'libdir', 'libfile.cpp'), 'w').write('''
- #include <stdio.h>
- void printey() {
- printf("hello from lib");
- }
- ''')
+ open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(r'''
+ #include <stdio.h>
+ extern void printey();
+ extern void printother();
+ int main() {
+ printf("*");
+ printey();
+ printf("\n");
+ printother();
+ printf("\n");
+ printf("*");
+ return 0;
+ }
+ ''')
- open(os.path.join(self.get_dir(), 'libdir', 'libother.cpp'), 'w').write('''
- #include <stdio.h>
- extern void printey();
- void printother() {
- printf("|");
- printey();
- printf("|");
- }
- ''')
+ try:
+ os.makedirs(os.path.join(self.get_dir(), 'libdir'));
+ except:
+ pass
- # This lets us link the same dynamic lib twice. We will need to link it in manually at the end.
- compiler = [PYTHON, EMCC, '--ignore-dynamic-linking']
+ open(os.path.join(self.get_dir(), 'libdir', 'libfile.cpp'), 'w').write('''
+ #include <stdio.h>
+ void printey() {
+ printf("hello from lib");
+ }
+ ''')
- # Build libfile normally into an .so
- Popen(compiler + [os.path.join(self.get_dir(), 'libdir', 'libfile.cpp'), '-o', os.path.join(self.get_dir(), 'libdir', 'libfile.so')]).communicate()
- # Build libother and dynamically link it to libfile - but add --ignore-dynamic-linking
- Popen(compiler + [os.path.join(self.get_dir(), 'libdir', 'libother.cpp'), '-L' + os.path.join(self.get_dir(), 'libdir'), '-lfile', '-o', os.path.join(self.get_dir(), 'libdir', 'libother.so')]).communicate()
- # Build the main file, linking in both the libs
- Popen(compiler + [os.path.join(self.get_dir(), 'main.cpp'), '-L' + os.path.join(self.get_dir(), 'libdir'), '-lfile', '-lother', '-c']).communicate()
+ open(os.path.join(self.get_dir(), 'libdir', 'libother.cpp'), 'w').write('''
+ #include <stdio.h>
+ extern void printey();
+ void printother() {
+ printf("|");
+ printey();
+ printf("|");
+ }
+ ''')
+
+ compiler = [PYTHON, EMCC]
+
+ # Build libfile normally into an .so
+ Popen(compiler + [os.path.join(self.get_dir(), 'libdir', 'libfile.cpp'), '-o', os.path.join(self.get_dir(), 'libdir', 'libfile.so' + lib_suffix)]).communicate()
+ # Build libother and dynamically link it to libfile
+ Popen(compiler + [os.path.join(self.get_dir(), 'libdir', 'libother.cpp')] + link_cmd + ['-o', os.path.join(self.get_dir(), 'libdir', 'libother.so')]).communicate()
+ # Build the main file, linking in both the libs
+ Popen(compiler + [os.path.join(self.get_dir(), 'main.cpp')] + link_cmd + ['-lother', '-c']).communicate()
+ print '...'
+ # The normal build system is over. We need to do an additional step to link in the dynamic libraries, since we ignored them before
+ Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.o')] + link_cmd + ['-lother']).communicate()
- # The normal build system is over. We need to do an additional step to link in the dynamic libraries, since we ignored them before
- Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.o'), '-L' + os.path.join(self.get_dir(), 'libdir'), '-lfile', '-lother']).communicate()
+ self.assertContained('*hello from lib\n|hello from lib|\n*', run_js(os.path.join(self.get_dir(), 'a.out.js')))
- self.assertContained('*hello from lib\n|hello from lib|\n*', run_js(os.path.join(self.get_dir(), 'a.out.js')))
+ test(['-L' + os.path.join(self.get_dir(), 'libdir'), '-lfile']) # -l, auto detection from library path
+ test(['-L' + os.path.join(self.get_dir(), 'libdir'), os.path.join(self.get_dir(), 'libdir', 'libfile.so.3.1.4.1.5.9')], '.3.1.4.1.5.9') # handle libX.so.1.2.3 as well
def test_js_link(self):
open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write('''
@@ -1785,6 +1798,7 @@ f.close()
assert 'If you see this - the world is all right!' in output
def test_embind(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
for args, fail in [
([], True), # without --bind, we fail
(['--bind'], False),
@@ -1850,6 +1864,8 @@ seeked= file.
assert output == invalid
def test_link_s(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo safe heap in fastcomp')
+
# -s OPT=VALUE can conflict with -s as a linker option. We warn and ignore
open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(r'''
extern "C" {
@@ -1944,19 +1960,19 @@ seeked= file.
# crunch should not be run if a .crn exists that is more recent than the .dds
shutil.copyfile(path_from_root('tests', 'ship.dds'), 'ship.dds')
time.sleep(0.1)
- Popen([PYTHON, FILE_PACKAGER, 'test.data', '--pre-run', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate()
+ Popen([PYTHON, FILE_PACKAGER, 'test.data', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate()
assert os.stat('test.data').st_size < 0.25*os.stat('ship.dds').st_size, 'Compressed should be much smaller than dds'
crunch_time = os.stat('ship.crn').st_mtime
dds_time = os.stat('ship.dds').st_mtime
assert crunch_time > dds_time, 'Crunch is more recent'
# run again, should not recrunch!
time.sleep(0.1)
- Popen([PYTHON, FILE_PACKAGER, 'test.data', '--pre-run', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate()
+ Popen([PYTHON, FILE_PACKAGER, 'test.data', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate()
assert crunch_time == os.stat('ship.crn').st_mtime, 'Crunch is unchanged'
# update dds, so should recrunch
time.sleep(0.1)
os.utime('ship.dds', None)
- Popen([PYTHON, FILE_PACKAGER, 'test.data', '--pre-run', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate()
+ Popen([PYTHON, FILE_PACKAGER, 'test.data', '--crunch=32', '--preload', 'ship.dds'], stdout=open('pre.js', 'w')).communicate()
assert crunch_time < os.stat('ship.crn').st_mtime, 'Crunch was changed'
def test_headless(self):
@@ -2133,6 +2149,8 @@ int main()
self.assertContained('File size: 722', out)
def test_simd(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
self.clear()
Popen([PYTHON, EMCC, path_from_root('tests', 'linpack.c'), '-O2', '-DSP', '--llvm-opts', '''['-O3', '-vectorize', '-vectorize-loops', '-bb-vectorize-vector-bits=128', '-force-vector-width=4']''']).communicate()
self.assertContained('Unrolled Single Precision', run_js('a.out.js'))
@@ -2181,3 +2199,12 @@ mergeInto(LibraryManager.library, {
out, err = process.communicate()
assert process.returncode is 0, 'float.h should agree with our system: ' + out + '\n\n\n' + err
+ def test_default_obj_ext(self):
+ outdir = os.path.join(self.get_dir(), 'out_dir') + '/'
+ os.mkdir(outdir)
+ process = Popen([PYTHON, EMCC, '-c', path_from_root('tests', 'hello_world.c'), '-o', outdir], stdout=PIPE, stderr=PIPE)
+ process.communicate()
+ assert(os.path.isfile(outdir + 'hello_world.o'))
+ process = Popen([PYTHON, EMCC, '-c', path_from_root('tests', 'hello_world.c'), '-o', outdir, '--default-obj-ext', 'obj'], stdout=PIPE, stderr=PIPE)
+ process.communicate()
+ assert(os.path.isfile(outdir + 'hello_world.obj'))
diff --git a/tests/test_sanity.py b/tests/test_sanity.py
index dc3d53db..e8b1f885 100644
--- a/tests/test_sanity.py
+++ b/tests/test_sanity.py
@@ -195,6 +195,34 @@ class sanity(RunnerCore):
finally:
del os.environ['EM_IGNORE_SANITY']
+ def test_llvm_fastcomp(self):
+ if os.environ.get('EMCC_FAST_COMPILER') != '1': return self.skip('not using fastcomp')
+
+ WARNING = 'fastcomp in use, but LLVM has not been built with the JavaScript backend as a target'
+
+ restore()
+
+ # Should see js backend during sanity check
+ assert check_fastcomp()
+ output = self.check_working(EMCC)
+ assert WARNING not in output, output
+
+ # Fake incorrect llc output, no mention of js backend
+ restore()
+ f = open(CONFIG_FILE, 'a')
+ f.write('LLVM_ROOT = "' + path_from_root('tests', 'fake') + '"')
+ f.close()
+
+ if not os.path.exists(path_from_root('tests', 'fake')):
+ os.makedirs(path_from_root('tests', 'fake'))
+
+ f = open(path_from_root('tests', 'fake', 'llc'), 'w')
+ f.write('#!/bin/sh\n')
+ f.write('echo "llc fake output\nRegistered Targets:\nno j-s backend for you!"')
+ f.close()
+ os.chmod(path_from_root('tests', 'fake', 'llc'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
+ output = self.check_working(EMCC, WARNING)
+
def test_node(self):
NODE_WARNING = 'node version appears too old'
NODE_WARNING_2 = 'cannot check node version'