diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/aniso.c | 5 | ||||
-rw-r--r-- | tests/cases/longjmp_tiny_invoke_phi.ll | 46 | ||||
-rw-r--r-- | tests/cases/longjmp_tiny_invoke_phi.txt | 4 | ||||
-rw-r--r-- | tests/core/closebitcasts.c | 32 | ||||
-rw-r--r-- | tests/core/closebitcasts.txt | 2 | ||||
-rw-r--r-- | tests/cubegeom.c | 12 | ||||
-rwxr-xr-x | tests/fuzz/test.sh | 52 | ||||
-rwxr-xr-x | tests/runner.py | 1 | ||||
-rw-r--r-- | tests/sdl_canvas.c | 2 | ||||
-rw-r--r-- | tests/test_benchmark.py | 6 | ||||
-rw-r--r-- | tests/test_browser.py | 21 | ||||
-rw-r--r-- | tests/test_core.py | 13 | ||||
-rw-r--r-- | tests/test_other.py | 127 | ||||
-rw-r--r-- | tests/test_sanity.py | 28 |
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' |