diff options
Diffstat (limited to 'tests')
33 files changed, 514 insertions, 111 deletions
diff --git a/tests/cases/fptosi.ll b/tests/cases/fptosi.ll new file mode 100644 index 00000000..71bc6af8 --- /dev/null +++ b/tests/cases/fptosi.ll @@ -0,0 +1,28 @@ +; ModuleID = '/dev/shm/tmp/src.cpp.o' +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" + +@.str = private unnamed_addr constant [8 x i8] c"*%.3f*\0A\00", align 1 ; [#uses=1 type=[8 x i8]*] +@.str2 = private unnamed_addr constant [6 x i8] c"*%d*\0A\00", align 1 ; [#uses=1 type=[6 x i8]*] + +; [#uses=0] +define i32 @main() { +entry: + %f = fadd float 1.000, 0.500 + %d = fadd double 3.333, 0.444 + %fd = fpext float %f to double + %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([8 x i8]* @.str, i32 0, i32 0), double %fd) ; [#uses=0 type=i32] + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([8 x i8]* @.str, i32 0, i32 0), double %d) ; [#uses=0 type=i32] + %fs = fptosi float %f to i64 + %fu = fptoui float %f to i64 + %ds = fptosi double %d to i64 + %du = fptoui double %d to i64 + %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str2, i32 0, i32 0), i64 %fs) ; [#uses=0 type=i32] + %call4 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str2, i32 0, i32 0), i64 %fu) ; [#uses=0 type=i32] + %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str2, i32 0, i32 0), i64 %ds) ; [#uses=0 type=i32] + %call6 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str2, i32 0, i32 0), i64 %du) ; [#uses=0 type=i32] + ret i32 1 +} + +; [#uses=1] +declare i32 @printf(i8*, ...) diff --git a/tests/cases/fptosi.txt b/tests/cases/fptosi.txt new file mode 100644 index 00000000..eea925c4 --- /dev/null +++ b/tests/cases/fptosi.txt @@ -0,0 +1,6 @@ +*1.500* +*3.777* +*1* +*1* +*3* +*3* diff --git a/tests/cases/longjmp_tiny_invoke.ll b/tests/cases/longjmp_tiny_invoke.ll index e1a72e00..6f856d49 100644 --- a/tests/cases/longjmp_tiny_invoke.ll +++ b/tests/cases/longjmp_tiny_invoke.ll @@ -9,7 +9,7 @@ target triple = "i386-pc-linux-gnu" define i32 @main() { %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, !dbg !20 + %call = invoke i32 @setjmp(i16* getelementptr inbounds ([20 x i16]* @_ZL3buf, i32 0, i32 0)) returns_twice to label %allgood unwind label %awful allgood: @@ -29,9 +29,13 @@ if.end: ; preds = %if.else, %if.then ret i32 0, !dbg !28 awful: + %Z = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup ret i32 1 } +declare i32 @__gxx_personality_v0(...) + declare i32 @setjmp(i16*) returns_twice declare i32 @printf(i8*, ...) diff --git a/tests/cases/longjmp_tiny_invoke_phi.ll b/tests/cases/longjmp_tiny_invoke_phi.ll index 30c43339..0df3f924 100644 --- a/tests/cases/longjmp_tiny_invoke_phi.ll +++ b/tests/cases/longjmp_tiny_invoke_phi.ll @@ -35,6 +35,8 @@ if.end: ; preds = %if.else, %if.then ret i32 0 awful: + %Z = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup ret i32 1 } @@ -44,3 +46,5 @@ declare i32 @printf(i8*, ...) declare void @longjmp(i16*, i32) +declare i32 @__gxx_personality_v0(...) + diff --git a/tests/cases/longjmp_tiny_phi.ll b/tests/cases/longjmp_tiny_phi.ll index cced7cab..21b936dd 100644 --- a/tests/cases/longjmp_tiny_phi.ll +++ b/tests/cases/longjmp_tiny_phi.ll @@ -28,7 +28,7 @@ if.else: ; preds = %entry br label %if.end if.end: ; preds = %if.else, %if.then - %aaa = phi i32 [ -1, %if.then ], [ 0, %if.else ], [ 1, %two ], [ 2, %entry ] + %aaa = phi i32 [ -1, %if.then ], [ 0, %if.else ] %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str2, i32 0, i32 0), i32 %aaa), !dbg !26 ret i32 %aaa, !dbg !28 } diff --git a/tests/cases/longjmp_tiny_phi2.ll b/tests/cases/longjmp_tiny_phi2.ll index 1d7761c3..88312fc6 100644 --- a/tests/cases/longjmp_tiny_phi2.ll +++ b/tests/cases/longjmp_tiny_phi2.ll @@ -24,7 +24,7 @@ if.then: ; preds = %entry br label %if.end, !dbg !25 if.end: ; preds = %if.else, %if.then - %aaa = phi i32 [ -1, %if.then ], [ 1, %two ], [ 2, %entry ] + %aaa = phi i32 [ -1, %if.then ], [ 1, %two ] %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str2, i32 0, i32 0), i32 %aaa), !dbg !26 ret i32 %aaa, !dbg !28 } diff --git a/tests/core/fnmatch.c b/tests/core/fnmatch.c new file mode 100644 index 00000000..ebdb2009 --- /dev/null +++ b/tests/core/fnmatch.c @@ -0,0 +1,79 @@ +// Begin test_fnmatch.cpp +#include <fnmatch.h> +#include <iostream> +#include <vector> +#include <string> + +using namespace std; + +class TestCase { +public: + TestCase(const string& pattern, const string& testString, int flags, int expected) : + pattern(pattern), + testString(testString), + flags(flags), + expected(expected) + {} + string pattern; + string testString; + int flags; + int expected; +}; + +int main() +{ + vector<TestCase> testCases; + + testCases.push_back(TestCase("*","anything",0,0)); + testCases.push_back(TestCase("*.txt","readme.txt",0,0)); + testCases.push_back(TestCase("*.txt","readme.info",0,FNM_NOMATCH)); + testCases.push_back(TestCase("*.t?t","readme.txt",0,0)); + testCases.push_back(TestCase("*.t?t","readme.tot",0,0)); + testCases.push_back(TestCase("*.t?t","readme.txxt",0,FNM_NOMATCH)); + testCases.push_back(TestCase("[a-g]1","c1",0,0)); + testCases.push_back(TestCase("[a-g]1","i1",0,FNM_NOMATCH)); + testCases.push_back(TestCase("[!a-g]1","i1",0,0)); + testCases.push_back(TestCase("a\\*","anything",0,FNM_NOMATCH)); + testCases.push_back(TestCase("a\\*","a*",0,0)); + testCases.push_back(TestCase("a\\*","a*",FNM_NOESCAPE,FNM_NOMATCH)); + testCases.push_back(TestCase("a\\*","a\\*",FNM_NOESCAPE,0)); + testCases.push_back(TestCase("*readme","/etc/readme",0,0)); + testCases.push_back(TestCase("*readme","/etc/readme",FNM_PATHNAME,FNM_NOMATCH)); + testCases.push_back(TestCase("/*/readme","/etc/readme",FNM_PATHNAME,0)); + testCases.push_back(TestCase("*readme","/etc/.readme",0,0)); + testCases.push_back(TestCase("*readme",".readme",FNM_PERIOD,FNM_NOMATCH)); + testCases.push_back(TestCase("*.readme","/etc/.readme",FNM_PERIOD,0)); + testCases.push_back(TestCase("*.readme","/etc/.readme",FNM_PERIOD|FNM_PATHNAME,FNM_NOMATCH)); + testCases.push_back(TestCase("/*/.readme","/etc/.readme",FNM_PERIOD|FNM_PATHNAME,0)); + testCases.push_back(TestCase("ReAdME","readme",0,FNM_NOMATCH)); + + bool pass = true; + + for (vector<TestCase>::const_iterator it = testCases.begin(); it != testCases.end(); ++it) + { + int result = fnmatch(it->pattern.c_str(), it->testString.c_str(), it->flags); + if (result == it->expected) + cout << "Pass: "; + else + { + cout << "Fail: "; + pass = false; + } + + cout << "fnmatch(" << it->pattern << ", " << it->testString << ", " + << it->flags << ") returned " << result << ", expected " + << it->expected << endl; + } + + if (pass) + { + cout << "All tests passed." << endl; + return 0; + } + else + { + cout << "Some tests failed." << endl; + return 1; + } +} + diff --git a/tests/core/fnmatch.out b/tests/core/fnmatch.out new file mode 100644 index 00000000..303f7449 --- /dev/null +++ b/tests/core/fnmatch.out @@ -0,0 +1,23 @@ +Pass: fnmatch(*, anything, 0) returned 0, expected 0 +Pass: fnmatch(*.txt, readme.txt, 0) returned 0, expected 0 +Pass: fnmatch(*.txt, readme.info, 0) returned 1, expected 1 +Pass: fnmatch(*.t?t, readme.txt, 0) returned 0, expected 0 +Pass: fnmatch(*.t?t, readme.tot, 0) returned 0, expected 0 +Pass: fnmatch(*.t?t, readme.txxt, 0) returned 1, expected 1 +Pass: fnmatch([a-g]1, c1, 0) returned 0, expected 0 +Pass: fnmatch([a-g]1, i1, 0) returned 1, expected 1 +Pass: fnmatch([!a-g]1, i1, 0) returned 0, expected 0 +Pass: fnmatch(a\*, anything, 0) returned 1, expected 1 +Pass: fnmatch(a\*, a*, 0) returned 0, expected 0 +Pass: fnmatch(a\*, a*, 2) returned 1, expected 1 +Pass: fnmatch(a\*, a\*, 2) returned 0, expected 0 +Pass: fnmatch(*readme, /etc/readme, 0) returned 0, expected 0 +Pass: fnmatch(*readme, /etc/readme, 1) returned 1, expected 1 +Pass: fnmatch(/*/readme, /etc/readme, 1) returned 0, expected 0 +Pass: fnmatch(*readme, /etc/.readme, 0) returned 0, expected 0 +Pass: fnmatch(*readme, .readme, 4) returned 1, expected 1 +Pass: fnmatch(*.readme, /etc/.readme, 4) returned 0, expected 0 +Pass: fnmatch(*.readme, /etc/.readme, 5) returned 1, expected 1 +Pass: fnmatch(/*/.readme, /etc/.readme, 5) returned 0, expected 0 +Pass: fnmatch(ReAdME, readme, 0) returned 1, expected 1 +All tests passed. diff --git a/tests/core/test_alloca.in b/tests/core/test_alloca.in index bfad3324..d115880f 100644 --- a/tests/core/test_alloca.in +++ b/tests/core/test_alloca.in @@ -1,9 +1,14 @@ #include <stdio.h> #include <stdlib.h> +#include <assert.h> -int main() { - char *pc; - pc = (char *)alloca(5); - printf("z:%d*%d*\n", pc > 0, (int)pc); +int main(int argc, char **argv) { + char *pc, *pc2; + assert(argc == 1); + pc = (char *)alloca(4+argc); + assert(((int)pc) % 4 == 0); + pc2 = (char *)alloca(4+argc); + assert(((int)pc2) % 4 == 0); + printf("z:%d*%d*%d*\n", pc > 0, (int)pc, (int)pc2); return 0; } diff --git a/tests/core/test_exception_2.in b/tests/core/test_exceptions_2.in index 2eae3198..2eae3198 100644 --- a/tests/core/test_exception_2.in +++ b/tests/core/test_exceptions_2.in diff --git a/tests/core/test_exception_2.out b/tests/core/test_exceptions_2.out index aa89c67d..aa89c67d 100644 --- a/tests/core/test_exception_2.out +++ b/tests/core/test_exceptions_2.out diff --git a/tests/core/test_multiexception.in b/tests/core/test_exceptions_multi.in index 46acbbf3..5453d11c 100644 --- a/tests/core/test_multiexception.in +++ b/tests/core/test_exceptions_multi.in @@ -22,9 +22,9 @@ void setjmp_func(jmp_state* s, int level) { s->jmp = c_jmp; setjmp_func(s, level + 1); } - catch (int catched_eid) { - printf("caught %d\n", catched_eid); - if (catched_eid == c_jmp) { + catch (int caught_eid) { + printf("caught %d\n", caught_eid); + if (caught_eid == c_jmp) { printf("setjmp exception execution path, level: %d, prev_jmp: %d\n", level, prev_jmp); if (prev_jmp != -1) { diff --git a/tests/core/test_multiexception.out b/tests/core/test_exceptions_multi.out index 33efe46e..33efe46e 100644 --- a/tests/core/test_multiexception.out +++ b/tests/core/test_exceptions_multi.out diff --git a/tests/core/test_std_exception.in b/tests/core/test_exceptions_std.in index 4b5905d8..3b9f874b 100644 --- a/tests/core/test_std_exception.in +++ b/tests/core/test_exceptions_std.in @@ -7,6 +7,7 @@ int main() { throw e; } catch (std::exception e) { + printf("what? %s\n", e.what()); printf("caught std::exception\n"); } return 0; diff --git a/tests/core/test_exceptions_std.out b/tests/core/test_exceptions_std.out new file mode 100644 index 00000000..eddab21c --- /dev/null +++ b/tests/core/test_exceptions_std.out @@ -0,0 +1,2 @@ +what? std::exception +caught std::exception diff --git a/tests/exceptions/typed.cpp b/tests/core/test_exceptions_typed.in index a2b77fee..a2b77fee 100644 --- a/tests/exceptions/typed.cpp +++ b/tests/core/test_exceptions_typed.in diff --git a/tests/exceptions/output.txt b/tests/core/test_exceptions_typed.out index 718f189a..718f189a 100644 --- a/tests/exceptions/output.txt +++ b/tests/core/test_exceptions_typed.out diff --git a/tests/core/test_white_list_exception.in b/tests/core/test_exceptions_white_list.in index 2944f9fe..2944f9fe 100644 --- a/tests/core/test_white_list_exception.in +++ b/tests/core/test_exceptions_white_list.in diff --git a/tests/core/test_white_list_exception.out b/tests/core/test_exceptions_white_list.out index 62e1a81c..62e1a81c 100644 --- a/tests/core/test_white_list_exception.out +++ b/tests/core/test_exceptions_white_list.out diff --git a/tests/core/test_inlinejs3.in b/tests/core/test_inlinejs3.in index 3e1913ff..e21ed041 100644 --- a/tests/core/test_inlinejs3.in +++ b/tests/core/test_inlinejs3.in @@ -3,7 +3,7 @@ int main(int argc, char **argv) { EM_ASM(Module.print('hello dere1')); - EM_ASM(Module.print('hello dere2');); + EM_ASM("Module.print('hello dere2');"); for (int i = 0; i < 3; i++) { EM_ASM(Module.print('hello dere3'); Module.print('hello dere' + 4);); } diff --git a/tests/core/test_nl_types.in b/tests/core/test_nl_types.in new file mode 100644 index 00000000..666920ee --- /dev/null +++ b/tests/core/test_nl_types.in @@ -0,0 +1,8 @@ +#include <nl_types.h> +#include <stdio.h> + +int main(int argc, char ** argv) { + nl_catd c = catopen("none", 0); + printf("Hello, %s.\n", catgets(c, 0, 0, "world")); + return catclose(c); +} diff --git a/tests/core/test_nl_types.out b/tests/core/test_nl_types.out new file mode 100644 index 00000000..f75ba05f --- /dev/null +++ b/tests/core/test_nl_types.out @@ -0,0 +1 @@ +Hello, world. diff --git a/tests/core/test_std_exception.out b/tests/core/test_std_exception.out deleted file mode 100644 index c1660de4..00000000 --- a/tests/core/test_std_exception.out +++ /dev/null @@ -1 +0,0 @@ -caught std::exception
\ No newline at end of file diff --git a/tests/core/test_wprintf.c b/tests/core/test_wprintf.c index e938bf69..b5f8d6ab 100644 --- a/tests/core/test_wprintf.c +++ b/tests/core/test_wprintf.c @@ -1,7 +1,44 @@ +#include <stdio.h> +#include <string.h> +#include <stdarg.h> #include <wchar.h> -int main() +void PrintWide ( const wchar_t * format, ... ) { + wchar_t buffer[256]; + memset(buffer, 0, 256); + va_list args; + va_start ( args, format ); + wprintf(L"format starts with 0x%x\n", *(int*)format); + wprintf(L"fmt continues with 0x%x\n", *(((int*)format) + 1)); + wprintf(L"fmt continues with 0x%x\n", *(((int*)format) + 2)); + int r = vswprintf ( buffer, 256, format, args ); + wprintf(L"vswprintf told us %d\n", r); + wprintf(L"vswoutput st-rts with 0x%x\n", *(int*)buffer); + wprintf(L"vsw continues with 0x%x\n", *(((int*)buffer) + 1)); + wprintf(L"vsw continues with 0x%x\n", *(((int*)buffer) + 2)); + wprintf(buffer); + va_end ( args ); +} + +int main () +{ + FILE *f = fopen("test.dat", "wb"); + int num = fwprintf(f, L"hello %d", 5); + wprintf(L"fwprintf told us %d\n", num); + fclose(f); + f = fopen("test.dat", "rb"); + fseek(f, 0, SEEK_END); + int size = ftell(f); + fclose(f); + wprintf(L"file size is %d\n", size); + + wchar_t str[] = L"test string has %d wide characters.\n"; + wprintf(L"str starts with 0x%x\n", *(int*)str); + wprintf(L"str continues with 0x%x\n", *(((int*)str) + 1)); + wprintf(L"str continues with 0x%x\n", *(((int*)str) + 2)); + PrintWide ( str, wcslen(str) ); + wprintf (L"Characters: %lc %lc \n", L'a', 65); wprintf (L"Decimals: %d %ld\n", 1977, 650000L); wprintf (L"Preceding with blanks: %10d \n", 1977); @@ -10,6 +47,17 @@ int main() wprintf (L"floats: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416); wprintf (L"Width trick: %*d \n", 5, 10); wprintf (L"%ls \n", L"A wide string"); + + wchar_t buffer [100]; + memset(buffer, 0, sizeof(buffer)); + int cx; + cx = swprintf(buffer, 100, L"The half of %d is %d", 80, 80/2); + wprintf(L"swprintf told us %d\n", cx); + for (int i = 0; i < 10; i++) wprintf(L"pre %d\n", ((int*)buffer)[i]); + swprintf (buffer+cx, 100-cx-1, L", and the half of that is %d.\n", 80/2/2); + for (int i = 0; i < 10; i++) wprintf(L"post %d\n", ((int*)buffer)[i]); + wprintf(buffer); + return 0; } diff --git a/tests/core/test_wprintf.out b/tests/core/test_wprintf.out index f85abebb..e074743d 100644 --- a/tests/core/test_wprintf.out +++ b/tests/core/test_wprintf.out @@ -1,3 +1,16 @@ +fwprintf told us 7 +file size is 7 +str starts with 0x74 +str continues with 0x65 +str continues with 0x73 +format starts with 0x74 +fmt continues with 0x65 +fmt continues with 0x73 +vswprintf told us 36 +vswoutput st-rts with 0x74 +vsw continues with 0x65 +vsw continues with 0x73 +test string has 36 wide characters. Characters: a A Decimals: 1977 650000 Preceding with blanks: 1977 @@ -6,3 +19,25 @@ Some different radixes: 100 64 144 0x64 0144 floats: 3.14 +3e+00 3.141600E+00 Width trick: 10 A wide string +swprintf told us 20 +pre 84 +pre 104 +pre 101 +pre 32 +pre 104 +pre 97 +pre 108 +pre 102 +pre 32 +pre 111 +post 84 +post 104 +post 101 +post 32 +post 104 +post 97 +post 108 +post 102 +post 32 +post 111 +The half of 80 is 40, and the half of that is 20. diff --git a/tests/doublestart.c b/tests/doublestart.c new file mode 100644 index 00000000..533e6308 --- /dev/null +++ b/tests/doublestart.c @@ -0,0 +1,23 @@ +#include <stdio.h> +#include <emscripten.h> + +int times = 0; + +void later(void* nada) { + int result = times; + REPORT_RESULT(); +} + +void main_loop(void) { + static int cnt = 0; + if (++cnt >= 10) emscripten_cancel_main_loop(); +} + +int main(void) { + emscripten_async_call(later, NULL, 2000); + times++; + printf("This should only appear once.\n"); + emscripten_set_main_loop(main_loop, 10, 0); + return 0; +} + diff --git a/tests/glew.c b/tests/glew.c new file mode 100644 index 00000000..3bf93fd9 --- /dev/null +++ b/tests/glew.c @@ -0,0 +1,51 @@ +#include <GL/glew.h> +#include <stdio.h> +#include <assert.h> +#include <string.h> + +/* for context creation */ +#include <SDL/SDL.h> + +int main() +{ + assert(SDL_Init(SDL_INIT_VIDEO) == 0); + assert(SDL_SetVideoMode(640, 480, 16, SDL_OPENGL) != NULL); + + assert(glewInit() == GLEW_OK); + assert(glewGetString(0) == NULL); + assert(!strcmp((const char*)glewGetString(1), "1.10.0")); + assert(!strcmp((const char*)glewGetString(2), "1")); + assert(!strcmp((const char*)glewGetString(3), "10")); + assert(!strcmp((const char*)glewGetString(4), "0")); + + for (int i = 0; i < 8; ++i) { + assert(glewGetErrorString(i) != NULL); + } + + assert(glewGetExtension("EXT_unexistant") == 0); + assert(glewIsSupported("EXT_unexistant EXT_foobar") == 0); + + /* we can't be sure about which extension exists, so lets do test on + * some of the common ones */ + if (GLEW_EXT_texture_filter_anisotropic) { + assert(glewGetExtension("EXT_texture_filter_anisotropic") == 1); + assert(glewGetExtension("GL_EXT_texture_filter_anisotropic") == 1); + } + + if (GLEW_EXT_framebuffer_object) { + assert(glewGetExtension("EXT_framebuffer_object") == 1); + assert(glewGetExtension("GL_EXT_framebuffer_object") == 1); + } + + if (GLEW_EXT_texture_filter_anisotropic && + GLEW_EXT_framebuffer_object) { + assert(glewIsSupported("EXT_texture_filter_anisotropic EXT_framebuffer_object") == 1); + assert(glewIsSupported("GL_EXT_texture_filter_anisotropic GL_EXT_framebuffer_object") == 1); + } + +#ifdef REPORT_RESULT + int result = 1; + REPORT_RESULT(); +#endif + return 0; +} diff --git a/tests/runner.py b/tests/runner.py index 7f0cbaed..f59d5cb9 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -36,7 +36,7 @@ except: # Core test runner class, shared between normal tests and benchmarks checked_sanity = False -test_modes = ['default', 'o1', 'o2', 'asm1', 'asm2', 'asm2f', 'asm2g', 'asm2x86', 's_0_0', 's_0_1'] +test_modes = ['default', 'o1', 'o2', 'asm1', 'asm2', 'asm3', 'asm2f', 'asm2g', 'asm2x86', 's_0_0', 's_0_1'] test_index = 0 class RunnerCore(unittest.TestCase): diff --git a/tests/test_benchmark.py b/tests/test_benchmark.py index 21a47178..1bf1c1d5 100644 --- a/tests/test_benchmark.py +++ b/tests/test_benchmark.py @@ -51,20 +51,21 @@ class Benchmarker: print class NativeBenchmarker(Benchmarker): - def __init__(self, name, cc, cxx): + def __init__(self, name, cc, cxx, args=['-O2']): self.name = name self.cc = cc self.cxx = cxx + self.args = args def build(self, parent, filename, args, shared_args, emcc_args, native_args, native_exec, lib_builder): self.parent = parent 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) + process = Popen([compiler, '-fno-math-errno', filename, '-o', filename+'.native'] + self.args + shared_args + native_args, stdout=PIPE, stderr=parent.stderr_redirect) output = process.communicate() if process.returncode is not 0: - print >> sys.stderr, "Building native executable with command '%s' failed with a return code %d!" % (' '.join([compiler, '-O2', filename, '-o', filename+'.native']), process.returncode) + print >> sys.stderr, "Building native executable with command failed" print "Output: " + output[0] else: shutil.copyfile(native_exec, filename + '.native') @@ -106,7 +107,7 @@ process(sys.argv[1]) final = os.path.dirname(filename) + os.path.sep + self.name+'_' + os.path.basename(filename) + '.js' try_delete(final) output = Popen([PYTHON, EMCC, filename, #'-O3', - '-O2', '-s', 'DOUBLE_MODE=0', '-s', 'PRECISE_I64_MATH=0', + '-O3', '-s', 'DOUBLE_MODE=0', '-s', 'PRECISE_I64_MATH=0', '--memory-init-file', '0', '--js-transform', 'python hardcode.py', '-s', 'TOTAL_MEMORY=128*1024*1024', #'--closure', '1', @@ -124,6 +125,7 @@ try: benchmarkers = [ #NativeBenchmarker('clang', CLANG_CC, CLANG), NativeBenchmarker('clang-3.2', os.path.join(LLVM_3_2, 'clang'), os.path.join(LLVM_3_2, 'clang++')), + #NativeBenchmarker('clang-3.2-O3', os.path.join(LLVM_3_2, 'clang'), os.path.join(LLVM_3_2, 'clang++'), ['-O3']), #NativeBenchmarker('clang-3.3', os.path.join(LLVM_3_3, 'clang'), os.path.join(LLVM_3_3, 'clang++')), #NativeBenchmarker('clang-3.4', os.path.join(LLVM_3_4, 'clang'), os.path.join(LLVM_3_4, 'clang++')), #NativeBenchmarker('gcc', 'gcc', 'g++'), @@ -472,7 +474,7 @@ class benchmark(RunnerCore): def lua(self, benchmark, expected, output_parser=None, args_processor=None): shutil.copyfile(path_from_root('tests', 'lua', benchmark + '.lua'), benchmark + '.lua') def lib_builder(name, native, env_init): - ret = self.get_library('lua', [os.path.join('src', 'lua'), os.path.join('src', 'liblua.a')], make=['make', 'generic'], configure=None, native=native, cache_name_extra=name, env_init=env_init) + ret = self.get_library('lua_native' if native else 'lua', [os.path.join('src', 'lua'), os.path.join('src', 'liblua.a')], make=['make', 'generic'], configure=None, native=native, cache_name_extra=name, env_init=env_init) if native: return ret shutil.copyfile(ret[0], ret[0] + '.bc') ret[0] += '.bc' diff --git a/tests/test_browser.py b/tests/test_browser.py index 27dffff2..02bcecbd 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -683,6 +683,9 @@ If manually bisecting: def test_sdl_canvas(self): self.btest('sdl_canvas.c', expected='1', args=['-s', 'LEGACY_GL_EMULATION=1']) + # some extra coverage + self.btest('sdl_canvas.c', expected='1', args=['-s', 'LEGACY_GL_EMULATION=1', '-s', '-O0', 'SAFE_HEAP=1']) + self.btest('sdl_canvas.c', expected='1', args=['-s', 'LEGACY_GL_EMULATION=1', '-s', '-O2', 'SAFE_HEAP=1']) def test_sdl_canvas_proxy(self): def post(): @@ -1602,6 +1605,10 @@ keydown(100);keyup(100); // trigger the end shutil.copyfile(path_from_root('tests', 'screenshot.dds'), os.path.join(self.get_dir(), 'screenshot.dds')) self.btest('s3tc.c', reference='s3tc.png', args=['--preload-file', 'screenshot.dds', '-s', 'LEGACY_GL_EMULATION=1']) + def test_s3tc_ffp_only(self): + shutil.copyfile(path_from_root('tests', 'screenshot.dds'), os.path.join(self.get_dir(), 'screenshot.dds')) + self.btest('s3tc.c', reference='s3tc.png', args=['--preload-file', 'screenshot.dds', '-s', 'LEGACY_GL_EMULATION=1', '-s', 'GL_FFP_ONLY=1']) + def test_s3tc_crunch(self): shutil.copyfile(path_from_root('tests', 'ship.dds'), 'ship.dds') shutil.copyfile(path_from_root('tests', 'bloom.dds'), 'bloom.dds') @@ -1749,4 +1756,21 @@ keydown(100);keyup(100); // trigger the end # Now run test in browser self.btest(path_from_root('tests', 'uuid', 'test.c'), '1') + def test_glew(self): + self.btest(path_from_root('tests', 'glew.c'), expected='1') + self.btest(path_from_root('tests', 'glew.c'), args=['-s', 'LEGACY_GL_EMULATION=1'], expected='1') + self.btest(path_from_root('tests', 'glew.c'), args=['-DGLEW_MX'], expected='1') + self.btest(path_from_root('tests', 'glew.c'), args=['-s', 'LEGACY_GL_EMULATION=1', '-DGLEW_MX'], expected='1') + + def test_doublestart_bug(self): + open('pre.js', 'w').write(r''' +if (typeof Module === 'undefined') Module = eval('(function() { try { return Module || {} } catch(e) { return {} } })()'); +if (!Module['preRun']) Module['preRun'] = []; +Module["preRun"].push(function () { + Module['addRunDependency']('test_run_dependency'); + Module['removeRunDependency']('test_run_dependency'); +}); +''') + + self.btest('doublestart.c', args=['--pre-js', 'pre.js', '-o', 'test.html'], expected='1') diff --git a/tests/test_core.py b/tests/test_core.py index d7bebdc6..d25847d7 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1117,74 +1117,48 @@ 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_longjmp(self): - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') - - test_path = path_from_root('tests', 'core', 'test_longjmp') - src, output = (test_path + s for s in ('.in', '.out')) - - self.do_run_from_file(src, output) + test_path = path_from_root('tests', 'core', 'test_longjmp') + src, output = (test_path + s for s in ('.in', '.out')) + self.do_run_from_file(src, output) def test_longjmp2(self): - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') - test_path = path_from_root('tests', 'core', 'test_longjmp2') src, output = (test_path + s for s in ('.in', '.out')) - self.do_run_from_file(src, output) def test_longjmp3(self): - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') - test_path = path_from_root('tests', 'core', 'test_longjmp3') src, output = (test_path + s for s in ('.in', '.out')) - self.do_run_from_file(src, output) def test_longjmp4(self): - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') - test_path = path_from_root('tests', 'core', 'test_longjmp4') src, output = (test_path + s for s in ('.in', '.out')) - self.do_run_from_file(src, output) def test_longjmp_funcptr(self): - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') - test_path = path_from_root('tests', 'core', 'test_longjmp_funcptr') src, output = (test_path + s for s in ('.in', '.out')) - self.do_run_from_file(src, output) def test_longjmp_repeat(self): - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') - - Settings.MAX_SETJMPS = 1 - - test_path = path_from_root('tests', 'core', 'test_longjmp_repeat') - src, output = (test_path + s for s in ('.in', '.out')) - - self.do_run_from_file(src, output) + Settings.MAX_SETJMPS = 1 + test_path = path_from_root('tests', 'core', 'test_longjmp_repeat') + src, output = (test_path + s for s in ('.in', '.out')) + self.do_run_from_file(src, output) def test_longjmp_stacked(self): - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') - test_path = path_from_root('tests', 'core', 'test_longjmp_stacked') src, output = (test_path + s for s in ('.in', '.out')) - self.do_run_from_file(src, output) - def test_longjmp_exc(self): - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') - test_path = path_from_root('tests', 'core', 'test_longjmp_exc') src, output = (test_path + s for s in ('.in', '.out')) - self.do_run_from_file(src, output) def test_setjmp_many(self): - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') + if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp: make MAX_SETJMPS take effect') src = r''' #include <stdio.h> @@ -1269,7 +1243,7 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co } catch (MyException & e) { - std::cout << "Catched..."; + std::cout << "Caught..."; } try @@ -1278,7 +1252,7 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co } catch (MyException e) { - std::cout << "Catched..."; + std::cout << "Caught..."; } return 0; @@ -1288,26 +1262,25 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co Settings.DISABLE_EXCEPTION_CATCHING = 0 if '-O2' in self.emcc_args: self.emcc_args.pop() ; self.emcc_args.pop() # disable closure to work around a closure bug - self.do_run(src, 'Throw...Construct...Catched...Destruct...Throw...Construct...Copy...Catched...Destruct...Destruct...') + self.do_run(src, 'Throw...Construct...Caught...Destruct...Throw...Construct...Copy...Caught...Destruct...Destruct...') - def test_exception_2(self): + def test_exceptions_2(self): if self.emcc_args is None: return self.skip('need emcc to add in libcxx properly') Settings.DISABLE_EXCEPTION_CATCHING = 0 - test_path = path_from_root('tests', 'core', 'test_exception_2') + test_path = path_from_root('tests', 'core', 'test_exceptions_2') src, output = (test_path + s for s in ('.in', '.out')) self.do_run_from_file(src, output) - - def test_white_list_exception(self): + def test_exceptions_white_list(self): if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') Settings.DISABLE_EXCEPTION_CATCHING = 2 Settings.EXCEPTION_CATCHING_WHITELIST = ["__Z12somefunctionv"] Settings.INLINING_LIMIT = 50 # otherwise it is inlined and not identified - test_path = path_from_root('tests', 'core', 'test_white_list_exception') + test_path = path_from_root('tests', 'core', 'test_exceptions_white_list') src, output = (test_path + s for s in ('.in', '.out')) self.do_run_from_file(src, output) @@ -1315,7 +1288,7 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co Settings.DISABLE_EXCEPTION_CATCHING = 0 Settings.EXCEPTION_CATCHING_WHITELIST = [] - def test_uncaught_exception(self): + def test_exceptions_uncaught(self): if self.emcc_args is None: return self.skip('no libcxx inclusion without emcc') Settings.DISABLE_EXCEPTION_CATCHING = 0 @@ -1354,29 +1327,27 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co ''' self.do_run(src, 'success') - def test_typed_exceptions(self): - Settings.DISABLE_EXCEPTION_CATCHING = 0 - Settings.SAFE_HEAP = 0 # Throwing null will cause an ignorable null pointer access. - src = open(path_from_root('tests', 'exceptions', 'typed.cpp'), 'r').read() - expected = open(path_from_root('tests', 'exceptions', 'output.txt'), 'r').read() - self.do_run(src, expected) - - def test_multiexception(self): - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') - + def test_exceptions_typed(self): Settings.DISABLE_EXCEPTION_CATCHING = 0 + Settings.SAFE_HEAP = 0 # Throwing null will cause an ignorable null pointer access. - test_path = path_from_root('tests', 'core', 'test_multiexception') + test_path = path_from_root('tests', 'core', 'test_exceptions_typed') src, output = (test_path + s for s in ('.in', '.out')) self.do_run_from_file(src, output) - def test_std_exception(self): + def test_exceptions_multi(self): + Settings.DISABLE_EXCEPTION_CATCHING = 0 + test_path = path_from_root('tests', 'core', 'test_exceptions_multi') + src, output = (test_path + s for s in ('.in', '.out')) + self.do_run_from_file(src, output) + + def test_exceptions_std(self): if self.emcc_args is None: return self.skip('requires emcc') Settings.DISABLE_EXCEPTION_CATCHING = 0 self.emcc_args += ['-s', 'SAFE_HEAP=0'] - test_path = path_from_root('tests', 'core', 'test_std_exception') + test_path = path_from_root('tests', 'core', 'test_exceptions_std') src, output = (test_path + s for s in ('.in', '.out')) self.do_run_from_file(src, output) @@ -1486,7 +1457,7 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co def test_segfault(self): if self.emcc_args is None: return self.skip('SAFE_HEAP without ta2 means we check types too, which hide segfaults') - if Settings.ASM_JS: return self.skip('asm does not support safe heap') + if os.environ.get('EMCC_FAST_COMPILER') == '1' and '-O2' not in self.emcc_args: return self.skip('todo in non-jsopts-enabled fastcomp') Settings.SAFE_HEAP = 1 @@ -1606,6 +1577,8 @@ 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_alloca(self): + if Settings.USE_TYPED_ARRAYS != 2: return self.skip('non-ta2 may have unaligned allocas') + test_path = path_from_root('tests', 'core', 'test_alloca') src, output = (test_path + s for s in ('.in', '.out')) @@ -3703,6 +3676,12 @@ ok self.do_run_from_file(src, output) + def test_fnmatch(self): + if self.emcc_args is None: return self.skip('requires linking in libc++') + test_path = path_from_root('tests', 'core', 'fnmatch') + src, output = (test_path + s for s in ('.c', '.out')) + self.do_run_from_file(src, output) + def test_sscanf(self): if self.emcc_args is None: return self.skip('needs emcc for libc') if not self.is_le32(): return self.skip('le32 needed for accurate math') @@ -4085,7 +4064,6 @@ def process(filename): def test_utf32(self): if self.emcc_args is None: return self.skip('need libc for wcslen()') if not self.is_le32(): return self.skip('this test uses inline js, which requires le32') - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') self.do_run(open(path_from_root('tests', 'utf32.cpp')).read(), 'OK.') self.do_run(open(path_from_root('tests', 'utf32.cpp')).read(), 'OK.', args=['-fshort-wchar']) @@ -4284,6 +4262,12 @@ def process(filename): self.do_run_from_file(src, output) + def test_nl_types(self): + test_path = path_from_root('tests', 'core', 'test_nl_types') + src, output = (test_path + s for s in ('.in', '.out')) + + self.do_run_from_file(src, output) + def test_799(self): src = open(path_from_root('tests', '799.cpp'), 'r').read() self.do_run(src, '''Set PORT family: 0, port: 3979 @@ -4620,6 +4604,7 @@ return malloc(size); assert 'asm1' in test_modes if self.run_name == 'asm1': generated = open('src.cpp.o.js').read() + generated = re.sub(r'\n+[ \n]*\n+', '\n', generated) 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') @@ -4642,6 +4627,8 @@ return malloc(size); self.do_run_from_file(src, output) def test_simd3(self): + return self.skip('FIXME: this appears to be broken') + if Settings.USE_TYPED_ARRAYS != 2: return self.skip('needs ta2') if Settings.ASM_JS: Settings.ASM_JS = 2 # does not validate @@ -4670,7 +4657,6 @@ return malloc(size); def test_lua(self): if self.emcc_args is None: return self.skip('requires emcc') if Settings.QUANTUM_SIZE == 1: return self.skip('TODO: make this work') - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') for aggro in ([0, 1] if Settings.ASM_JS and '-O2' in self.emcc_args else [0]): print aggro @@ -4691,7 +4677,6 @@ return malloc(size); 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 os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') assert 'asm2g' in test_modes if self.run_name == 'asm2g': @@ -4837,7 +4822,6 @@ def process(filename): def test_poppler(self): if self.emcc_args is None: return self.skip('very slow, we only do this in emcc runs') - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') Settings.CORRECT_OVERFLOWS = 1 Settings.CORRECT_SIGNS = 1 @@ -4999,7 +4983,9 @@ def process(filename): def clean(text): text = text.replace('\n\n', '\n').replace('\n\n', '\n').replace('\n\n', '\n').replace('\n\n', '\n').replace('\n\n', '\n').replace('{\n}', '{}') return '\n'.join(sorted(text.split('\n'))) - self.assertIdentical(clean(open('release.js').read()), clean(open('debug%d.js' % debug).read())) # EMCC_DEBUG=1 mode must not generate different code! + sizes = len(open('release.js').read()), len(open('debug%d.js' % debug).read()) + print >> sys.stderr, debug, 'sizes', sizes + assert abs(sizes[0] - sizes[1]) < 0.0001*sizes[0] # we can't check on identical output, compilation is not 100% deterministic (order of switch elements, etc.), but size should be ~identical print >> sys.stderr, 'debug check %d passed too' % debug try: @@ -5057,7 +5043,7 @@ 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', 'longjmp_tiny_invoke_phi', 'indirectbrphi', 'ptrtoint_blockaddr', 'quoted', # current fastcomp limitations FIXME + 'indirectbrphi', 'ptrtoint_blockaddr', 'quoted', # current fastcomp limitations FIXME 'sillyfuncast2', 'sillybitcast', 'atomicrmw_unaligned' # TODO XXX ]: continue if '_ta2' in shortname and not Settings.USE_TYPED_ARRAYS == 2: @@ -5968,7 +5954,7 @@ def process(filename): def test_debug(self): if '-g' not in Building.COMPILER_TEST_OPTS: Building.COMPILER_TEST_OPTS.append('-g') if self.emcc_args is not None: - if '-O1' in self.emcc_args or '-O2' in self.emcc_args: return self.skip('optimizations remove LLVM debug info') + if '-O1' in self.emcc_args or '-O2' in self.emcc_args or '-O3' in self.emcc_args: return self.skip('optimizations remove LLVM debug info') src = ''' #include <stdio.h> @@ -5999,7 +5985,6 @@ def process(filename): def test_source_map(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip("doesn't pass without typed arrays") - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') if NODE_JS not in JS_ENGINES: return self.skip('sourcemapper requires Node to run') if '-g' not in Building.COMPILER_TEST_OPTS: Building.COMPILER_TEST_OPTS.append('-g') @@ -6046,6 +6031,7 @@ def process(filename): # optimizer can deal with both types. out_file = re.sub(' *//@.*$', '', out_file, flags=re.MULTILINE) def clean(code): + code = re.sub(r'\n+[ \n]*\n+', '\n', code) code = code.replace('{\n}', '{}') return '\n'.join(sorted(code.split('\n'))) self.assertIdentical(clean(no_maps_file), clean(out_file)) @@ -6083,7 +6069,6 @@ def process(filename): if Settings.USE_TYPED_ARRAYS != 2: return self.skip("doesn't pass without typed arrays") if '-g4' not in Building.COMPILER_TEST_OPTS: Building.COMPILER_TEST_OPTS.append('-g4') if NODE_JS not in JS_ENGINES: return self.skip('sourcemapper requires Node to run') - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') src = ''' #include <stdio.h> @@ -6108,7 +6093,7 @@ def process(filename): tools.shared.NODE_JS, [map_filename])) with open(filename) as f: lines = f.readlines() for m in mappings: - if m['originalLine'] == 5 and '__cxa_throw' in lines[m['generatedLine']]: + if m['originalLine'] == 5 and '__cxa_throw' in lines[m['generatedLine']-1]: # -1 to fix 0-start vs 1-start return assert False, 'Must label throw statements with line numbers' @@ -6358,7 +6343,7 @@ def make_run(fullname, name=-1, compiler=-1, embetter=0, quantum_size=0, if self.emcc_args is not None: Settings.load(self.emcc_args) Building.LLVM_OPTS = 0 - if '-O2' in self.emcc_args: + if '-O2' in self.emcc_args or '-O3' in self.emcc_args: Building.COMPILER_TEST_OPTS = [] # remove -g in -O2 tests, for more coverage #Building.COMPILER_TEST_OPTS += self.emcc_args for arg in self.emcc_args: @@ -6412,8 +6397,12 @@ o2 = make_run("o2", compiler=CLANG, emcc_args=["-O2", "-s", "ASM_JS=0", "-s", "J # asm.js asm1 = make_run("asm1", compiler=CLANG, emcc_args=["-O1"]) asm2 = make_run("asm2", compiler=CLANG, emcc_args=["-O2"]) +asm3 = make_run("asm3", compiler=CLANG, emcc_args=["-O3"]) asm2f = make_run("asm2f", compiler=CLANG, emcc_args=["-O2", "-s", "PRECISE_F32=1"]) -asm2g = make_run("asm2g", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "ASSERTIONS=1", "--memory-init-file", "1", "-s", "CHECK_HEAP_ALIGN=1"]) +if os.environ.get('EMCC_FAST_COMPILER') == '1': + asm2g = make_run("asm2g", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "ASSERTIONS=1", "--memory-init-file", "1", "-s", "SAFE_HEAP=1"]) +else: + 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 f91b4683..53128391 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -134,13 +134,13 @@ Options that are modified or new in %s include: (['-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), - (['-o', 'something.js', '-O3', '-s', 'ASM_JS=0'], 3, None, 1, 1), + (['-o', 'something.js', '-O3', '-s', 'ASM_JS=0'], 3, None, 0, 1), # and, test compiling to bitcode first (['-o', 'something.bc'], 0, [], 0, 0), (['-o', 'something.bc', '-O0'], 0, [], 0, 0), (['-o', 'something.bc', '-O1'], 1, ['-O1'], 0, 0), (['-o', 'something.bc', '-O2'], 2, ['-O2'], 0, 0), - (['-o', 'something.bc', '-O3'], 3, ['-O3', '-s', 'ASM_JS=0'], 1, 0), + (['-o', 'something.bc', '-O3'], 3, ['-O3', '-s', 'ASM_JS=0'], 0, 0), (['-O1', '-o', 'something.bc'], 1, [], 0, 0), ]: print params, opt_level, bc_params, closure, has_malloc @@ -157,7 +157,6 @@ Options that are modified or new in %s include: print '....', bc_args output = Popen(bc_args, stdout=PIPE, stderr=PIPE).communicate() assert os.path.exists('something.js'), output[1] - assert ('Applying some potentially unsafe optimizations!' in output[1]) == (opt_level >= 3), 'unsafe warning should appear in opt >= 3' self.assertContained('hello, world!', run_js('something.js')) # Verify optimization level etc. in the generated code @@ -196,7 +195,6 @@ Options that are modified or new in %s include: (['-O2', '-g3'], lambda generated: 'var b=0' not in generated and 'var b = 0' not in generated and 'function _main' in generated, 'registerize is cancelled by -g3'), #(['-O2', '-g4'], lambda generated: 'var b=0' not in generated and 'var b = 0' not in generated and 'function _main' in generated, 'same as -g3 for now'), (['-s', 'INLINING_LIMIT=0'], lambda generated: 'function _dump' in generated, 'no inlining without opts'), - (['-O3', '-s', 'INLINING_LIMIT=0', '--closure', '0'], lambda generated: 'function _dump' not in generated, 'lto/inlining'), (['-Os', '--llvm-lto', '1', '-s', 'ASM_JS=0', '-g2'], lambda generated: 'function _dump' in generated, '-Os disables inlining'), (['-s', 'USE_TYPED_ARRAYS=0'], lambda generated: 'new Int32Array' not in generated, 'disable typed arrays'), (['-s', 'USE_TYPED_ARRAYS=1'], lambda generated: 'IHEAPU = ' in generated, 'typed arrays 1 selected'), @@ -284,9 +282,33 @@ f.close() if WINDOWS: generators = ['MinGW Makefiles', 'NMake Makefiles'] else: - generators = ['Unix Makefiles'] - - make_commands = { 'MinGW Makefiles': ['mingw32-make'], 'NMake Makefiles': ['nmake', '/NOLOGO'], 'Unix Makefiles': ['make'] } + generators = ['Unix Makefiles', 'Ninja', 'Eclipse CDT4 - Ninja'] + + def nmake_detect_error(configuration): + if Building.which(configuration['build'][0]): + return None + else: + return 'Skipping NMake test for CMake support, since nmake was not found in PATH. Run this test in Visual Studio command prompt to easily access nmake.' + + def check_makefile(configuration, dirname): + assert os.path.exists(dirname + '/Makefile'), 'CMake call did not produce a Makefile!' + + configurations = { 'MinGW Makefiles' : { 'prebuild': check_makefile, + 'build' : ['mingw32-make'], + + }, + 'NMake Makefiles' : { 'detect' : nmake_detect_error, + 'prebuild': check_makefile, + 'build' : ['nmake', '/NOLOGO'], + }, + 'Unix Makefiles' : { 'prebuild': check_makefile, + 'build' : ['make'], + }, + 'Ninja' : { 'build' : ['ninja'], + }, + 'Eclipse CDT4 - Ninja': { 'build' : ['ninja'], + } + } if os.name == 'nt': emconfigure = path_from_root('emconfigure.bat') @@ -294,11 +316,37 @@ f.close() emconfigure = path_from_root('emconfigure') for generator in generators: - if generator == 'NMake Makefiles' and not Building.which('nmake'): - print >> sys.stderr, 'Skipping NMake test for CMake support, since nmake was not found in PATH. Run this test in Visual Studio command prompt to easily access nmake.' + conf = configurations[generator] + + make = conf['build'] + + try: + detector = conf['detect'] + except KeyError: + detector = None + + if detector: + error = detector(conf) + elif len(make) == 1 and not Building.which(make[0]): + # Use simple test if applicable + error = 'Skipping %s test for CMake support, since it could not be detected.' % generator + else: + error = None + + if error: + logging.warning(error) continue - make = make_commands[generator] + try: + prebuild = conf['prebuild'] + except KeyError: + prebuild = None + + try: + postbuild = conf['postbuild'] + except KeyError: + postbuild = None + cmake_cases = ['target_js', 'target_html'] cmake_outputs = ['test_cmake.js', 'hello_world_gles.html'] for i in range(0, 2): @@ -331,7 +379,9 @@ f.close() logging.error('Failed command: ' + ' '.join(cmd)) logging.error('Result:\n' + ret[1]) raise Exception('cmake call failed!') - assert os.path.exists(tempdirname + '/Makefile'), 'CMake call did not produce a Makefile!' + + if prebuild: + prebuild(configuration, tempdirname) # Build cmd = make + (['VERBOSE=1'] if verbose_level >= 3 else []) @@ -344,6 +394,9 @@ f.close() raise Exception('make failed!') assert os.path.exists(tempdirname + '/' + cmake_outputs[i]), 'Building a cmake-generated Makefile failed to produce an output file %s!' % tempdirname + '/' + cmake_outputs[i] + if postbuild: + postbuild(configuration, tempdirname) + # Run through node, if CMake produced a .js file. if cmake_outputs[i].endswith('.js'): ret = Popen(listify(NODE_JS) + [tempdirname + '/' + cmake_outputs[i]], stdout=PIPE).communicate()[0] @@ -1721,7 +1774,7 @@ f.close() (path_from_root('tools', 'test-js-optimizer-asm-regs.js'), open(path_from_root('tools', 'test-js-optimizer-asm-regs-output.js')).read(), ['asm', 'registerize']), (path_from_root('tools', 'test-js-optimizer-asm-regs-min.js'), open(path_from_root('tools', 'test-js-optimizer-asm-regs-min-output.js')).read(), - ['asm', 'registerize']), + ['asm', 'registerize', 'minifyLocals']), (path_from_root('tools', 'test-js-optimizer-asm-pre.js'), open(path_from_root('tools', 'test-js-optimizer-asm-pre-output.js')).read(), ['asm', 'simplifyExpressions']), (path_from_root('tools', 'test-js-optimizer-asm-last.js'), open(path_from_root('tools', 'test-js-optimizer-asm-last-output.js')).read(), @@ -1736,6 +1789,8 @@ f.close() ['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']), + (path_from_root('tools', 'test-js-optimizer-shiftsAggressive.js'), open(path_from_root('tools', 'test-js-optimizer-shiftsAggressive-output.js')).read(), + ['asm', 'aggressiveVariableElimination']), ]: print input output = Popen(listify(NODE_JS) + [path_from_root('tools', 'js-optimizer.js'), input] + passes, stdin=PIPE, stdout=PIPE).communicate()[0] @@ -2219,7 +2274,6 @@ mergeInto(LibraryManager.library, { process.communicate() assert(os.path.isfile(outdir + 'hello_world.obj')) - def test_doublestart_bug(self): open('code.cpp', 'w').write(r''' #include <stdio.h> @@ -2251,3 +2305,20 @@ Module["preRun"].push(function () { assert output.count('This should only appear once.') == 1, '\n'+output + def test_module_print(self): + open('code.cpp', 'w').write(r''' +#include <stdio.h> +int main(void) { + printf("123456789\n"); + return 0; +} +''') + + open('pre.js', 'w').write(r''' +var Module = { print: function(x) { throw '<{(' + x + ')}>' } }; +''') + + Popen([PYTHON, EMCC, 'code.cpp', '--pre-js', 'pre.js']).communicate() + output = run_js(os.path.join(self.get_dir(), 'a.out.js'), stderr=PIPE, full_output=True, engine=NODE_JS) + assert r'<{(123456789)}>' in output, output + diff --git a/tests/utf32.cpp b/tests/utf32.cpp index 6b75b244..d00338a6 100644 --- a/tests/utf32.cpp +++ b/tests/utf32.cpp @@ -16,11 +16,11 @@ int main() { if (sizeof(wchar_t) == 4) { utf32 *memory = new utf32[wstr.length()+1]; - asm("var str = Module.UTF32ToString(%0);" - "Module.print(str);" - "Module.stringToUTF32(str, %1);" - : - : "r"(wstr.c_str()), "r"(memory)); + EM_ASM_INT({ + var str = Module.UTF32ToString($0); + Module.print(str); + Module.stringToUTF32(str, $1); + }, wstr.c_str(), memory); // Compare memory to confirm that the string is intact after taking a route through JS side. const utf32 *srcPtr = reinterpret_cast<const utf32 *>(wstr.c_str()); @@ -33,11 +33,11 @@ int main() { } else { // sizeof(wchar_t) == 2, and we're building with -fshort-wchar. utf16 *memory = new utf16[2*wstr.length()+1]; - asm("var str = Module.UTF16ToString(%0);" - "Module.print(str);" - "Module.stringToUTF16(str, %1);" - : - : "r"(wstr.c_str()), "r"(memory)); + EM_ASM_INT({ + var str = Module.UTF16ToString($0); + Module.print(str); + Module.stringToUTF16(str, $1); + }, wstr.c_str(), memory); // Compare memory to confirm that the string is intact after taking a route through JS side. const utf16 *srcPtr = reinterpret_cast<const utf16 *>(wstr.c_str()); |