diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/cases/fp80_ta2.ll | 21 | ||||
-rw-r--r-- | tests/cases/phiptrtoint.ll | 138 | ||||
-rw-r--r-- | tests/cases/phiptrtoint.txt | 0 | ||||
-rw-r--r-- | tests/cases/sub_11_0.ll | 16 | ||||
-rw-r--r-- | tests/gles2_uniform_arrays.cpp | 121 | ||||
-rwxr-xr-x | tests/runner.py | 9 | ||||
-rw-r--r-- | tests/sdl_rotozoom.c | 2 | ||||
-rw-r--r-- | tests/sdl_rotozoom.png | bin | 431168 -> 711242 bytes | |||
-rw-r--r-- | tests/stdio/test_rename.c | 10 | ||||
-rw-r--r-- | tests/test_browser.py | 6 | ||||
-rw-r--r-- | tests/test_core.py | 106 | ||||
-rw-r--r-- | tests/test_other.py | 80 | ||||
-rw-r--r-- | tests/test_sanity.py | 9 |
13 files changed, 442 insertions, 76 deletions
diff --git a/tests/cases/fp80_ta2.ll b/tests/cases/fp80_ta2.ll deleted file mode 100644 index 7fc0db4a..00000000 --- a/tests/cases/fp80_ta2.ll +++ /dev/null @@ -1,21 +0,0 @@ -; ModuleID = '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" -target triple = "i386-pc-linux-gnu" - -@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00" ; [#uses=1] - -; [#uses=0] -define i32 @main() { -entry: - %x = zext i32 0 to x86_fp80 - %1 = bitcast x86_fp80 %x to i80 - %2 = trunc i80 %1 to i32 - %retval = alloca i32, align 4 ; [#uses=1] - store i32 0, i32* %retval - %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0] - ret i32 0 -} - -; [#uses=1] -declare i32 @printf(i8*, ...) - diff --git a/tests/cases/phiptrtoint.ll b/tests/cases/phiptrtoint.ll new file mode 100644 index 00000000..d682dc06 --- /dev/null +++ b/tests/cases/phiptrtoint.ll @@ -0,0 +1,138 @@ +; ModuleID = '/tmp/tmpJctwj0/bug.bc' +; just an asm validation check, no output +target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32" +target triple = "le32-unknown-nacl" + +%"class.test::Processor" = type { i32, %"class.test::StateMachine" } +%"class.test::StateMachine" = type { { i32, i32 } } + +@_ZN4test9ProcessorC1Ev = alias internal void (%"class.test::Processor"*)* @_ZN4test9ProcessorC2Ev +@_ZN4test9ProcessorD1Ev = alias internal void (%"class.test::Processor"*)* @_ZN4test9ProcessorD2Ev + +define internal void @_ZN4test9ProcessorC2Ev(%"class.test::Processor"* nocapture %this) unnamed_addr nounwind align 2 { + %1 = getelementptr inbounds %"class.test::Processor"* %this, i32 0, i32 0 + store i32 0, i32* %1, align 4 + %2 = getelementptr inbounds %"class.test::Processor"* %this, i32 0, i32 1, i32 0 + store { i32, i32 } zeroinitializer, { i32, i32 }* %2, align 4 + ret void +} + +define internal void @_ZN4test9ProcessorD2Ev(%"class.test::Processor"* nocapture %this) unnamed_addr nounwind readnone align 2 { + ret void +} + +define internal zeroext i1 @_ZN4test9Processor16handleFirstStateEv(%"class.test::Processor"* nocapture %this) align 2 { + %1 = tail call i32 @rand() + %2 = getelementptr inbounds %"class.test::Processor"* %this, i32 0, i32 0 + %3 = load i32* %2, align 4 + %4 = add nsw i32 %3, %1 + store i32 %4, i32* %2, align 4 + %5 = and i32 %4, 1 + %6 = icmp eq i32 %5, 0 + ret i1 %6 +} + +declare i32 @rand() + +define internal zeroext i1 @_ZN4test9Processor15handleLastStateEv(%"class.test::Processor"* nocapture %this) align 2 { + %1 = tail call i32 @rand() + %2 = getelementptr inbounds %"class.test::Processor"* %this, i32 0, i32 0 + %3 = load i32* %2, align 4 + %4 = add nsw i32 %3, %1 + store i32 %4, i32* %2, align 4 + ret i1 true +} + +define internal zeroext i1 @_ZN4test9Processor3runEv(%"class.test::Processor"* %this) align 2 { + %1 = getelementptr inbounds %"class.test::Processor"* %this, i32 0, i32 1, i32 0 + store { i32, i32 } { i32 ptrtoint (i1 (%"class.test::Processor"*)* @_ZN4test9Processor16handleFirstStateEv to i32), i32 0 }, { i32, i32 }* %1, align 4 + %2 = bitcast %"class.test::Processor"* %this to i8* + br label %.backedge + +.backedge: ; preds = %25, %..backedge_crit_edge, %0 + %3 = phi { i32, i32 } [ { i32 ptrtoint (i1 (%"class.test::Processor"*)* @_ZN4test9Processor16handleFirstStateEv to i32), i32 0 }, %0 ], [ %.pre.pre, %..backedge_crit_edge ], [ { i32 ptrtoint (i1 (%"class.test::Processor"*)* @_ZN4test9Processor15handleLastStateEv to i32), i32 0 }, %25 ] + %.fca.0.extract = extractvalue { i32, i32 } %3, 0 + %.fca.1.extract = extractvalue { i32, i32 } %3, 1 + %4 = icmp ne i32 %.fca.0.extract, ptrtoint (i1 (%"class.test::Processor"*)* @_ZN4test9Processor15handleLastStateEv to i32) + %5 = icmp ne i32 %.fca.0.extract, 0 + %6 = icmp ne i32 %.fca.1.extract, 0 + %7 = and i1 %5, %6 + %8 = or i1 %4, %7 + %9 = getelementptr inbounds i8* %2, i32 %.fca.1.extract + %10 = bitcast i8* %9 to %"class.test::Processor"* + %11 = and i32 %.fca.0.extract, 1 + %12 = icmp eq i32 %11, 0 + br i1 %12, label %20, label %13 + +; <label>:13 ; preds = %.backedge + %14 = bitcast i8* %9 to i8** + %15 = load i8** %14, align 4 + %16 = add i32 %.fca.0.extract, -1 + %17 = getelementptr i8* %15, i32 %16 + %18 = bitcast i8* %17 to i1 (%"class.test::Processor"*)** + %19 = load i1 (%"class.test::Processor"*)** %18, align 4 + br label %_ZN4test12StateMachineINS_9ProcessorEE11handleStateEPS1_.exit + +; <label>:20 ; preds = %.backedge + %21 = inttoptr i32 %.fca.0.extract to i1 (%"class.test::Processor"*)* + br label %_ZN4test12StateMachineINS_9ProcessorEE11handleStateEPS1_.exit + +_ZN4test12StateMachineINS_9ProcessorEE11handleStateEPS1_.exit: ; preds = %20, %13 + %22 = phi i1 (%"class.test::Processor"*)* [ %19, %13 ], [ %21, %20 ] + %23 = tail call zeroext i1 %22(%"class.test::Processor"* %10) + br i1 %8, label %24, label %26 + +; <label>:24 ; preds = %_ZN4test12StateMachineINS_9ProcessorEE11handleStateEPS1_.exit + br i1 %23, label %25, label %..backedge_crit_edge + +..backedge_crit_edge: ; preds = %24 + %.pre.pre = load { i32, i32 }* %1, align 4 + br label %.backedge + +; <label>:25 ; preds = %24 + store { i32, i32 } { i32 ptrtoint (i1 (%"class.test::Processor"*)* @_ZN4test9Processor15handleLastStateEv to i32), i32 0 }, { i32, i32 }* %1, align 4 + br label %.backedge + +; <label>:26 ; preds = %_ZN4test12StateMachineINS_9ProcessorEE11handleStateEPS1_.exit + ret i1 %23 +} + +define internal i32 @_ZNK4test9Processor6resultEv(%"class.test::Processor"* nocapture %this) nounwind readonly align 2 { + %1 = getelementptr inbounds %"class.test::Processor"* %this, i32 0, i32 0 + %2 = load i32* %1, align 4 + ret i32 %2 +} + +define i32 @runProcess() { + %processor = alloca %"class.test::Processor", align 4 + call void @_ZN4test9ProcessorC1Ev(%"class.test::Processor"* %processor) + %1 = invoke zeroext i1 @_ZN4test9Processor3runEv(%"class.test::Processor"* %processor) + to label %2 unwind label %5 + +; <label>:2 ; preds = %0 + %3 = invoke i32 @_ZNK4test9Processor6resultEv(%"class.test::Processor"* %processor) + to label %4 unwind label %5 + +; <label>:4 ; preds = %2 + call void @_ZN4test9ProcessorD1Ev(%"class.test::Processor"* %processor) + ret i32 %3 + +; <label>:5 ; preds = %2, %0 + %6 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + invoke void @_ZN4test9ProcessorD1Ev(%"class.test::Processor"* %processor) + to label %7 unwind label %8 + +; <label>:7 ; preds = %5 + resume { i8*, i32 } %6 + +; <label>:8 ; preds = %5 + %9 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + call void @_ZSt9terminatev() noreturn nounwind + unreachable +} + +declare i32 @__gxx_personality_v0(...) + +declare void @_ZSt9terminatev() diff --git a/tests/cases/phiptrtoint.txt b/tests/cases/phiptrtoint.txt new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/tests/cases/phiptrtoint.txt diff --git a/tests/cases/sub_11_0.ll b/tests/cases/sub_11_0.ll new file mode 100644 index 00000000..7f0bb285 --- /dev/null +++ b/tests/cases/sub_11_0.ll @@ -0,0 +1,16 @@ +; ModuleID = 'tests/hello_world.bc' + +@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*] + +; [#uses=0] +define i32 @main() { +entry: + %retval = alloca i32, align 4 ; [#uses=1 type=i32*] + %0 = sub nsw i32 1, 1 + store i32 %0, i32* %retval + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0 type=i32] + ret i32 1 +} + +; [#uses=1] +declare i32 @printf(i8*, ...) diff --git a/tests/gles2_uniform_arrays.cpp b/tests/gles2_uniform_arrays.cpp new file mode 100644 index 00000000..84e394dc --- /dev/null +++ b/tests/gles2_uniform_arrays.cpp @@ -0,0 +1,121 @@ +#include "SDL/SDL_opengl.h" +#include "SDL/SDL.h" + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +void RunTest(int testVariant) +{ + GLuint vs = 0; + + const char *vsCode = "#version 100\n" + "attribute vec4 pos; void main() { gl_Position = pos; }"; + + vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vsCode, NULL); + glCompileShader(vs); + + GLuint ps = 0; + + const char *psCode = "#version 100\n" + "precision lowp float;\n" + "uniform vec3 color;\n" + "uniform vec3 colors[3];\n" + "void main() { gl_FragColor = vec4(color,1) + vec4(colors[0].r, colors[1].g, colors[2].b, 1); }"; + + ps = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(ps, 1, &psCode, NULL); + glCompileShader(ps); + + GLuint program = 0; + program = glCreateProgram(); + glAttachShader(program, vs); + glAttachShader(program, ps); + glBindAttribLocation(program, 0, "pos"); + glLinkProgram(program); + + int color_loc = glGetUniformLocation(program, "color"); + assert(color_loc != -1); + + glUseProgram(program); + float col[3] = { 0.2f, 0.2f, 0.2f }; + glUniform3fv(color_loc, 1, col); + + int loc = glGetUniformLocation(program, "colors"); + assert(loc != -1); + // In previous Emscripten GL layer code, calling glGetUniformLocation would do extra caching operations that interacts how glUniform** after that will work, + // so to exhibit extra issues in old code (and to keep new code from regressing), must test both with and without excess glGetUniformLocation calls. + if ((testVariant&1) != 0) + { + // Deliberately check in odd order to make sure any kind of lazy operations won't affect the indices we get. + assert(glGetUniformLocation(program, "colors[2]") == loc+2); + assert(glGetUniformLocation(program, "colors[0]") == loc); + assert(glGetUniformLocation(program, "colors[3]") == -1); + assert(glGetUniformLocation(program, "colors[1]") == loc+1); + assert(glGetUniformLocation(program, "colors[]") == loc); + assert(glGetUniformLocation(program, "colors[-100]") == -1); + assert(glGetUniformLocation(program, "colors[bleh]") == -1); + } + + float colors[4*3] = { 1,0,0, 0,0.5,0, 0,0,0.2, 1,1,1 }; + + if ((testVariant&2)!=0) + { + glUniform3fv(loc+1, 3, colors+3); // Pass the actual colors (testing a nonzero location offset), but do a mistake by setting one index too many. Spec says this should be gracefully handled, and that excess elements are ignored. + assert(glGetError() == GL_NO_ERROR); + glUniform3fv(loc, 1, colors); // Set the first index as well. + assert(glGetError() == GL_NO_ERROR); + } + else + { + glUniform3fv(loc, 4, colors); // Just directly set the full array. + assert(glGetError() == GL_NO_ERROR); + } + + assert(glGetError() == GL_NO_ERROR); + + GLuint vbo = 0; + const GLfloat v[] = { -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1 }; + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW); + + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), 0); + glEnableVertexAttribArray(0); + + glDrawArrays(GL_TRIANGLES, 0, 6); + + unsigned char pixel[4]; + glReadPixels(1,1,1,1,GL_RGBA,GL_UNSIGNED_BYTE, pixel); + //printf("%d,%d,%d,%d\n", pixel[0], pixel[1], pixel[2], pixel[3]); + assert(pixel[0] == 255); + assert(pixel[1] == 178); + assert(pixel[2] == 102); + assert(pixel[3] == 255); + + printf("OK: Case %d passed.\n", testVariant); + // Lazy, don't clean up afterwards. +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + + // Slightly different SDL initialization + if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { + printf("Unable to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed* + if ( !screen ) { + printf("Unable to set video mode: %s\n", SDL_GetError()); + return 1; + } + + for(int i = 0; i < 4; ++i) + RunTest(i); + + return 0; +} diff --git a/tests/runner.py b/tests/runner.py index ddc97ea4..867f7113 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -737,13 +737,15 @@ if __name__ == '__main__': print ''' ============================================================================== Running the main part of the test suite. Don't forget to run the other parts! +A recommended order is: - other - tests separate from the main suite sanity - tests for first run, etc., modifies ~/.emscripten - benchmark - run before and after each set of changes before pushing to - master, verify no regressions + (the main test suite) + other - tests separate from the main suite browser - runs pages in a web browser sockets - runs websocket networking tests + benchmark - run before and after each set of changes before pushing to + master, verify no regressions There are also commands to run specific subsets of the test suite: @@ -799,3 +801,4 @@ an individual test with # Return the number of failures as the process exit code for automating success/failure reporting. exit(numFailures) + diff --git a/tests/sdl_rotozoom.c b/tests/sdl_rotozoom.c index cdbdcc6f..2c0d35df 100644 --- a/tests/sdl_rotozoom.c +++ b/tests/sdl_rotozoom.c @@ -38,7 +38,7 @@ int main(int argc, char **argv) { sprite[2] = zoomSurface(sprite[0], 0.5, 0.5, SMOOTHING_ON); sprite[3] = zoomSurface(sprite[1], 0.5, 0.5, SMOOTHING_ON); sprite[4] = rotozoomSurface(sprite[0], -20, 0.3, SMOOTHING_ON); - sprite[5] = rotozoomSurface(sprite[1], 45, 0.5, SMOOTHING_ON); + sprite[5] = rotozoomSurface(sprite[1], 20, 1, SMOOTHING_ON); sprite[6] = zoomSurface(sprite[0], -0.5, 0.5, SMOOTHING_ON); sprite[7] = zoomSurface(sprite[0], -0.5, -0.5, SMOOTHING_ON); sprite[8] = rotozoomSurface(sprite[1], 0, 0.5, SMOOTHING_ON); diff --git a/tests/sdl_rotozoom.png b/tests/sdl_rotozoom.png Binary files differindex 5933754f..ebde79f2 100644 --- a/tests/sdl_rotozoom.png +++ b/tests/sdl_rotozoom.png diff --git a/tests/stdio/test_rename.c b/tests/stdio/test_rename.c index f15c8140..1a5017c1 100644 --- a/tests/stdio/test_rename.c +++ b/tests/stdio/test_rename.c @@ -25,6 +25,8 @@ void setup() { mkdir("dir/subdir", 0777); mkdir("dir-readonly", 0555); mkdir("dir-nonempty", 0777); + mkdir("dir/subdir3", 0777); + mkdir("dir/subdir3/subdir3_1", 0777); create_file("dir-nonempty/file", "abcdef", 0777); } @@ -38,6 +40,9 @@ void cleanup() { rmdir("dir/subdir"); rmdir("dir/subdir1"); rmdir("dir/subdir2"); + rmdir("dir/subdir3/subdir3_1/subdir1 renamed"); + rmdir("dir/subdir3/subdir3_1"); + rmdir("dir/subdir3"); rmdir("dir"); rmdir("dir-readonly"); unlink("dir-nonempty/file"); @@ -96,6 +101,11 @@ void test() { err = access("dir/subdir2", F_OK); assert(!err); + err = rename("dir/subdir2", "dir/subdir3/subdir3_1/subdir1 renamed"); + assert(!err); + err = access("dir/subdir3/subdir3_1/subdir1 renamed", F_OK); + assert(!err); + puts("success"); } diff --git a/tests/test_browser.py b/tests/test_browser.py index f4e4b89a..ecd331fd 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -1311,6 +1311,10 @@ keydown(100);keyup(100); // trigger the end def test_gl_vertex_buffer(self): self.btest('gl_vertex_buffer.c', reference='gl_vertex_buffer.png', args=['-s', 'GL_UNSAFE_OPTS=0', '-s', 'LEGACY_GL_EMULATION=1'], reference_slack=1) + # Does not pass due to https://bugzilla.mozilla.org/show_bug.cgi?id=924264 so disabled for now. + # def test_gles2_uniform_arrays(self): + # self.btest('gles2_uniform_arrays.cpp', args=['-s', 'GL_ASSERTIONS=1'], expected=['1']) + def test_matrix_identity(self): self.btest('gl_matrix_identity.c', expected=['-1882984448', '460451840'], args=['-s', 'LEGACY_GL_EMULATION=1']) @@ -1388,7 +1392,7 @@ keydown(100);keyup(100); // trigger the end def test_sdl_rotozoom(self): shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) - self.btest('sdl_rotozoom.c', reference='sdl_rotozoom.png', args=['--preload-file', 'screenshot.png'], reference_slack=5) + self.btest('sdl_rotozoom.c', reference='sdl_rotozoom.png', args=['--preload-file', 'screenshot.png']) def test_sdl_gfx_primitives(self): self.btest('sdl_gfx_primitives.c', reference='sdl_gfx_primitives.png', reference_slack=1) diff --git a/tests/test_core.py b/tests/test_core.py index f51c1691..87925082 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1073,7 +1073,6 @@ Succeeded! self.do_run(open(path_from_root('tests', 'cube2md5.cpp')).read(), open(path_from_root('tests', 'cube2md5.ok')).read()) def test_cube2hash(self): - try: old_chunk_size = os.environ.get('EMSCRIPT_MAX_CHUNK_SIZE') or '' os.environ['EMSCRIPT_MAX_CHUNK_SIZE'] = '1' # test splitting out each function to a chunk in emscripten.py (21 functions here) @@ -1091,6 +1090,17 @@ Succeeded! finally: os.environ['EMSCRIPT_MAX_CHUNK_SIZE'] = old_chunk_size + assert 'asm1' in test_modes + if self.run_name == 'asm1': + assert Settings.RELOOP + generated = open('src.cpp.o.js').read() + main = generated[generated.find('function _main'):] + main = main[:main.find('\n}')] + num_vars = 0 + for v in re.findall('var [^;]+;', main): + num_vars += v.count(',') + 1 + assert num_vars == 10, 'no variable elimination should have been run, but seeing %d' % num_vars + def test_unaligned(self): if Settings.QUANTUM_SIZE == 1: return self.skip('No meaning to unaligned addresses in q1') @@ -3841,25 +3851,26 @@ def process(filename): self.do_run(src, '4\n200\ndone\n') def test_inlinejs3(self): - if Settings.ASM_JS: return self.skip('asm does not support random code, TODO: something that works in asm') - src = r''' - #include <stdio.h> - #include <emscripten.h> + src = r''' + #include <stdio.h> + #include <emscripten.h> - int main() { - EM_ASM(Module.print('hello dere1')); - EM_ASM( - Module.print('hello dere2'); - ); + int main() { + EM_ASM(Module.print('hello dere1')); + EM_ASM( + Module.print('hello dere2'); + ); + for (int i = 0; i < 3; i++) { EM_ASM( Module.print('hello dere3'); Module.print('hello dere' + 4); ); - return 0; } - ''' + return 0; + } + ''' - self.do_run(src, 'hello dere1\nhello dere2\nhello dere3\nhello dere4\n') + self.do_run(src, 'hello dere1\nhello dere2\nhello dere3\nhello dere4\nhello dere3\nhello dere4\nhello dere3\nhello dere4\n') def test_memorygrowth(self): if Settings.USE_TYPED_ARRAYS == 0: return self.skip('memory growth is only supported with typed arrays') @@ -7266,6 +7277,7 @@ date: 18.07.2013w; day 18, month 7, year 2013, extra: 201, 3 if self.emcc_args is not None and '-O2' in self.emcc_args: self.emcc_args += ['--closure', '1'] # Use closure here, to test we don't break FS stuff self.emcc_args = filter(lambda x: x != '-g', self.emcc_args) # ensure we test --closure 1 --memory-init-file 1 (-g would disable closure) + self.emcc_args += ["-s", "CHECK_HEAP_ALIGN=0"] # disable heap align check here, it mixes poorly with closure Settings.CORRECT_SIGNS = 1 # Just so our output is what we expect. Can flip them both. post = ''' @@ -7743,20 +7755,20 @@ def process(filename): Settings.INCLUDE_FULL_LIBRARY = 0 def test_fs_nodefs_rw(self): + if self.emcc_args is None: return self.skip('requires emcc') + if not self.is_le32(): return self.skip('le32 needed for inline js') src = open(path_from_root('tests', 'fs', 'test_nodefs_rw.c'), 'r').read() - self.do_run(src, 'success', force_c=True) + self.do_run(src, 'success', force_c=True, js_engines=[NODE_JS]) def test_unistd_access(self): - if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code if not self.is_le32(): return self.skip('le32 needed for inline js') for fs in ['MEMFS', 'NODEFS']: src = open(path_from_root('tests', 'unistd', 'access.c'), 'r').read() expected = open(path_from_root('tests', 'unistd', 'access.out'), 'r').read() Building.COMPILER_TEST_OPTS += ['-D' + fs] - self.do_run(src, expected) + self.do_run(src, expected, js_engines=[NODE_JS]) def test_unistd_curdir(self): - if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code if not self.is_le32(): return self.skip('le32 needed for inline js') src = open(path_from_root('tests', 'unistd', 'curdir.c'), 'r').read() expected = open(path_from_root('tests', 'unistd', 'curdir.out'), 'r').read() @@ -7787,13 +7799,12 @@ def process(filename): self.do_run(src, expected) def test_unistd_truncate(self): - if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code if not self.is_le32(): return self.skip('le32 needed for inline js') for fs in ['MEMFS', 'NODEFS']: src = open(path_from_root('tests', 'unistd', 'truncate.c'), 'r').read() expected = open(path_from_root('tests', 'unistd', 'truncate.out'), 'r').read() Building.COMPILER_TEST_OPTS += ['-D' + fs] - self.do_run(src, expected) + self.do_run(src, expected, js_engines=[NODE_JS]) def test_unistd_swab(self): src = open(path_from_root('tests', 'unistd', 'swab.c'), 'r').read() @@ -7815,19 +7826,20 @@ def process(filename): self.do_run(src, expected) def test_unistd_unlink(self): + if self.emcc_args is None: return self.skip('requires emcc') + if not self.is_le32(): return self.skip('le32 needed for inline js') for fs in ['MEMFS', 'NODEFS']: src = open(path_from_root('tests', 'unistd', 'unlink.c'), 'r').read() Building.COMPILER_TEST_OPTS += ['-D' + fs] - self.do_run(src, 'success', force_c=True) + self.do_run(src, 'success', force_c=True, js_engines=[NODE_JS]) def test_unistd_links(self): - if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code if not self.is_le32(): return self.skip('le32 needed for inline js') for fs in ['MEMFS', 'NODEFS']: src = open(path_from_root('tests', 'unistd', 'links.c'), 'r').read() expected = open(path_from_root('tests', 'unistd', 'links.out'), 'r').read() Building.COMPILER_TEST_OPTS += ['-D' + fs] - self.do_run(src, expected) + self.do_run(src, expected, js_engines=[NODE_JS]) def test_unistd_sleep(self): src = open(path_from_root('tests', 'unistd', 'sleep.c'), 'r').read() @@ -7835,21 +7847,23 @@ def process(filename): self.do_run(src, expected) def test_unistd_io(self): - if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code if not self.is_le32(): return self.skip('le32 needed for inline js') if self.run_name == 'o2': return self.skip('non-asm optimized builds can fail with inline js') + if self.emcc_args is None: return self.skip('requires emcc') for fs in ['MEMFS', 'NODEFS']: src = open(path_from_root('tests', 'unistd', 'io.c'), 'r').read() expected = open(path_from_root('tests', 'unistd', 'io.out'), 'r').read() Building.COMPILER_TEST_OPTS += ['-D' + fs] - self.do_run(src, expected) + self.do_run(src, expected, js_engines=[NODE_JS]) def test_unistd_misc(self): + if self.emcc_args is None: return self.skip('requires emcc') + if not self.is_le32(): return self.skip('le32 needed for inline js') for fs in ['MEMFS', 'NODEFS']: src = open(path_from_root('tests', 'unistd', 'misc.c'), 'r').read() expected = open(path_from_root('tests', 'unistd', 'misc.out'), 'r').read() Building.COMPILER_TEST_OPTS += ['-D' + fs] - self.do_run(src, expected) + self.do_run(src, expected, js_engines=[NODE_JS]) def test_uname(self): src = r''' @@ -8602,6 +8616,13 @@ void*:16 assert ' & 255]()' not in original, 'big function table does not exist' assert ' & 255]()' in final, 'big function table exists' + assert 'asm1' in test_modes + if self.run_name == 'asm1': + generated = open('src.cpp.o.js').read() + main = generated[generated.find('function runPostSets'):] + main = main[:main.find('\n}')] + assert main.count('\n') == 7, 'must not emit too many postSets: %d' % main.count('\n') + def test_gcc_unmangler(self): Settings.NAMED_GLOBALS = 1 # test coverage for this @@ -8639,7 +8660,10 @@ void*:16 def test_freetype(self): if self.emcc_args is None: return self.skip('requires emcc') if Settings.QUANTUM_SIZE == 1: return self.skip('TODO: Figure out and try to fix') - if Settings.ASM_JS and '-O2' not in self.emcc_args: return self.skip('mozilla bug 863867') + + assert 'asm2g' in test_modes + if self.run_name == 'asm2g': + Settings.ALIASING_FUNCTION_POINTERS = 1 - Settings.ALIASING_FUNCTION_POINTERS # flip for some more coverage here if Settings.CORRECT_SIGNS == 0: Settings.CORRECT_SIGNS = 1 # Not sure why, but needed @@ -9452,6 +9476,32 @@ def process(filename): Settings.ALIASING_FUNCTION_POINTERS = 1 - Settings.ALIASING_FUNCTION_POINTERS # flip the test self.do_run(src, '''Hello 7 from JS!''') + def test_demangle_stacks(self): + if Settings.ASM_JS: return self.skip('spidermonkey has stack trace issues') + + src = r''' + #include<stdio.h> + #include<stdlib.h> + + namespace NameSpace { + class Class { + public: + int Aborter(double x, char y, int *z) { + int addr = x+y+(int)z; + void *p = (void*)addr; + for (int i = 0; i < 100; i++) free(p); // will abort, should show proper stack trace + } + }; + } + + int main(int argc, char **argv) { + NameSpace::Class c; + c.Aborter(1.234, 'a', NULL); + return 0; + } + ''' + self.do_run(src, 'NameSpace::Class::Aborter(double, char, int*)'); + def test_embind(self): if self.emcc_args is None: return self.skip('requires emcc') Building.COMPILER_TEST_OPTS += ['--bind'] @@ -10510,9 +10560,9 @@ o1 = make_run("o1", compiler=CLANG, emcc_args=["-O1", "-s", "ASM_JS=0", "-s", "S o2 = make_run("o2", compiler=CLANG, emcc_args=["-O2", "-s", "ASM_JS=0", "-s", "JS_CHUNK_SIZE=1024"]) # asm.js -asm1 = make_run("asm1", compiler=CLANG, emcc_args=["-O1", "-s", "CHECK_HEAP_ALIGN=1"]) +asm1 = make_run("asm1", compiler=CLANG, emcc_args=["-O1"]) asm2 = make_run("asm2", compiler=CLANG, emcc_args=["-O2"]) -asm2g = make_run("asm2g", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "ASSERTIONS=1", "--memory-init-file", "1"]) +asm2g = make_run("asm2g", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "ASSERTIONS=1", "--memory-init-file", "1", "-s", "CHECK_HEAP_ALIGN=1"]) asm2x86 = make_run("asm2x86", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "CHECK_HEAP_ALIGN=1"], env={"EMCC_LLVM_TARGET": "i386-pc-linux-gnu"}) # Make custom runs with various options diff --git a/tests/test_other.py b/tests/test_other.py index 9f331439..185b4853 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -125,8 +125,6 @@ Options that are modified or new in %s include: (['-o', 'something.js', '-O0'], 0, None, 0, 0), (['-o', 'something.js', '-O1'], 1, None, 0, 0), (['-o', 'something.js', '-O1', '-g'], 1, None, 0, 0), # no closure since debug - (['-o', 'something.js', '-O1', '--closure', '1'], 1, None, 1, 0), - (['-o', 'something.js', '-O1', '--closure', '1', '-s', 'ASM_JS=0'], 1, None, 1, 0), (['-o', 'something.js', '-O2'], 2, None, 0, 1), (['-o', 'something.js', '-O2', '-g'], 2, None, 0, 0), (['-o', 'something.js', '-Os'], 2, None, 0, 1), @@ -169,13 +167,13 @@ Options that are modified or new in %s include: # closure has not been run, we can do some additional checks. TODO: figure out how to do these even with closure assert '._main = ' not in generated, 'closure compiler should not have been run' if keep_debug: - assert ('(label)' in generated or '(label | 0)' in generated) == (opt_level <= 1), 'relooping should be in opt >= 2' + assert ('(label)' in generated or '(label | 0)' in generated) == (opt_level <= 0), 'relooping should be in opt >= 1' assert ('assert(STACKTOP < STACK_MAX' in generated) == (opt_level == 0), 'assertions should be in opt == 0' - assert 'var $i;' in generated or 'var $i_0' in generated or 'var $storemerge3;' in generated or 'var $storemerge4;' in generated or 'var $i_04;' in generated or 'var $original = 0' in generated, 'micro opts should always be on' + assert 'var $i;' in generated or 'var $i_0' in generated or 'var $storemerge3;' in generated or 'var $storemerge4;' in generated or '$i_04' in generated or '$i_05' in generated or 'var $original = 0' in generated, 'micro opts should always be on' if opt_level >= 2 and '-g' in params: assert re.search('HEAP8\[\$?\w+ ?\+ ?\(+\$?\w+ ?', generated) or re.search('HEAP8\[HEAP32\[', generated), 'eliminator should create compound expressions, and fewer one-time vars' # also in -O1, but easier to test in -O2 assert ('_puts(' in generated) == (opt_level >= 1), 'with opt >= 1, llvm opts are run and they should optimize printf to puts' - if opt_level == 0 or '-g' in params: assert 'function _main() {' in generated, 'Should be unminified, including whitespace' + if opt_level == 0 or '-g' in params: assert 'function _main() {' in generated or 'function _main(){' in generated, 'Should be unminified' elif opt_level >= 2: assert ('function _main(){' in generated or '"use asm";var a=' in generated), 'Should be whitespace-minified' # emcc -s RELOOP=1 src.cpp ==> should pass -s to emscripten.py. --typed-arrays is a convenient alias for -s USE_TYPED_ARRAYS @@ -807,10 +805,10 @@ f.close() 0: (1500, 5000) }), (['-O2'], { - 100: (0, 1500), - 250: (0, 1500), - 500: (0, 1500), - 1000: (0, 1500), + 100: (0, 1600), + 250: (0, 1600), + 500: (0, 1600), + 1000: (0, 1600), 2000: (0, 2000), 5000: (0, 5000), 0: (0, 5000) @@ -1647,6 +1645,8 @@ f.close() ['asm', 'outline']), (path_from_root('tools', 'test-js-optimizer-asm-outline3.js'), open(path_from_root('tools', 'test-js-optimizer-asm-outline3-output.js')).read(), ['asm', 'outline']), + (path_from_root('tools', 'test-js-optimizer-asm-minlast.js'), open(path_from_root('tools', 'test-js-optimizer-asm-minlast-output.js')).read(), + ['asm', 'minifyWhitespace', 'last']), ]: print input output = Popen(listify(NODE_JS) + [path_from_root('tools', 'js-optimizer.js'), input] + passes, stdin=PIPE, stdout=PIPE).communicate()[0] @@ -1666,20 +1666,16 @@ f.close() try: os.environ['EMCC_DEBUG'] = '1' os.environ['EMCC_CORES'] = '2' # standardize over machines - for asm, linkable, chunks, js_chunks in [ - (0, 0, 2, 2), (0, 1, 2, 4), - (1, 0, 2, 2), (1, 1, 2, 4) + for asm, linkable, chunks in [ + (0, 0, 2), (0, 1, 2), + (1, 0, 2), (1, 1, 2) ]: - print asm, linkable, chunks, js_chunks + print asm, linkable, chunks output, err = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_libcxx.cpp'), '-O1', '-s', 'LINKABLE=%d' % linkable, '-s', 'ASM_JS=%d' % asm] + (['-O2'] if asm else []), stdout=PIPE, stderr=PIPE).communicate() ok = False for c in range(chunks, chunks+2): ok = ok or ('phase 2 working on %d chunks' % c in err) assert ok, err - ok = False - for c in range(js_chunks, js_chunks+2): - ok = ok or ('splitting up js optimization into %d chunks' % c in err) - assert ok, err finally: del os.environ['EMCC_DEBUG'] del os.environ['EMCC_CORES'] @@ -1910,3 +1906,53 @@ done. assert '''tests/hello_world.c"''' in out assert '''printf("hello, world!''' in out + def test_demangle(self): + open('src.cpp', 'w').write(''' + #include <stdio.h> + #include <emscripten.h> + void two(char c) { + EM_ASM(Module.print(stackTrace())); + } + void one(int x) { + two(x % 17); + } + int main() { + EM_ASM(Module.print(demangle('__Znwj'))); // check for no aborts + EM_ASM(Module.print(demangle('_main'))); + EM_ASM(Module.print(demangle('__Z2f2v'))); + EM_ASM(Module.print(demangle('__Z12abcdabcdabcdi'))); + EM_ASM(Module.print(demangle('__Z4testcsifdPvPiPc'))); + EM_ASM(Module.print(demangle('__ZN4test5moarrEcslfdPvPiPc'))); + EM_ASM(Module.print(demangle('__ZN4Waka1f12a234123412345pointEv'))); + EM_ASM(Module.print(demangle('__Z3FooIiEvv'))); + EM_ASM(Module.print(demangle('__Z3FooIidEvi'))); + EM_ASM(Module.print(demangle('__ZN3Foo3BarILi5EEEvv'))); + EM_ASM(Module.print(demangle('__ZNK10__cxxabiv120__si_class_type_info16search_below_dstEPNS_19__dynamic_cast_infoEPKvib'))); + EM_ASM(Module.print(demangle('__Z9parsewordRPKciRi'))); + EM_ASM(Module.print(demangle('__Z5multiwahtjmxyz'))); + EM_ASM(Module.print(demangle('__Z1aA32_iPA5_c'))); + one(17); + return 0; + } + ''') + + Popen([PYTHON, EMCC, 'src.cpp', '-s', 'LINKABLE=1']).communicate() + output = run_js('a.out.js') + self.assertContained('''main +f2() +abcdabcdabcd(int) +test(char, short, int, float, double, void*, int*, char*) +test::moarr(char, short, long, float, double, void*, int*, char*) +Waka::f::a23412341234::point() +void Foo<int>() +void Foo<int, double>(int) +void Foo::Bar<5>() +__cxxabiv1::__si_class_type_info::search_below_dst(__cxxabiv1::__dynamic_cast_info*, void*, int, bool) +parseword(char*&, int, int&) +multi(wchar_t, signed char, unsigned char, unsigned short, unsigned int, unsigned long, long long, unsigned long long, |