aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/cases/fptosi.ll28
-rw-r--r--tests/cases/fptosi.txt6
-rw-r--r--tests/cases/longjmp_tiny_invoke.ll6
-rw-r--r--tests/cases/longjmp_tiny_invoke_phi.ll4
-rw-r--r--tests/cases/longjmp_tiny_phi.ll2
-rw-r--r--tests/cases/longjmp_tiny_phi2.ll2
-rw-r--r--tests/core/fnmatch.c79
-rw-r--r--tests/core/fnmatch.out23
-rw-r--r--tests/core/test_alloca.in13
-rw-r--r--tests/core/test_exceptions_2.in (renamed from tests/core/test_exception_2.in)0
-rw-r--r--tests/core/test_exceptions_2.out (renamed from tests/core/test_exception_2.out)0
-rw-r--r--tests/core/test_exceptions_multi.in (renamed from tests/core/test_multiexception.in)6
-rw-r--r--tests/core/test_exceptions_multi.out (renamed from tests/core/test_multiexception.out)0
-rw-r--r--tests/core/test_exceptions_std.in (renamed from tests/core/test_std_exception.in)1
-rw-r--r--tests/core/test_exceptions_std.out2
-rw-r--r--tests/core/test_exceptions_typed.in (renamed from tests/exceptions/typed.cpp)0
-rw-r--r--tests/core/test_exceptions_typed.out (renamed from tests/exceptions/output.txt)0
-rw-r--r--tests/core/test_exceptions_white_list.in (renamed from tests/core/test_white_list_exception.in)0
-rw-r--r--tests/core/test_exceptions_white_list.out (renamed from tests/core/test_white_list_exception.out)0
-rw-r--r--tests/core/test_inlinejs3.in2
-rw-r--r--tests/core/test_nl_types.in8
-rw-r--r--tests/core/test_nl_types.out1
-rw-r--r--tests/core/test_std_exception.out1
-rw-r--r--tests/core/test_wprintf.c50
-rw-r--r--tests/core/test_wprintf.out35
-rw-r--r--tests/doublestart.c23
-rw-r--r--tests/glew.c51
-rwxr-xr-xtests/runner.py2
-rw-r--r--tests/test_benchmark.py12
-rw-r--r--tests/test_browser.py24
-rw-r--r--tests/test_core.py127
-rw-r--r--tests/test_other.py97
-rw-r--r--tests/utf32.cpp20
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());