aboutsummaryrefslogtreecommitdiff
path: root/tests/runner.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/runner.py')
-rwxr-xr-xtests/runner.py776
1 files changed, 550 insertions, 226 deletions
diff --git a/tests/runner.py b/tests/runner.py
index 5602fd94..570bfbf2 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -78,6 +78,8 @@ class RunnerCore(unittest.TestCase):
stderr_redirect = STDOUT # This avoids cluttering the test runner output, which is stderr too, with compiler warnings etc.
# Change this to None to get stderr reporting, for debugging purposes
+ env = {}
+
def skipme(self): # used by tests we ask on the commandline to be skipped, see right before call to unittest.main
return self.skip('requested to be skipped')
@@ -238,10 +240,7 @@ process(sys.argv[1])
os.remove(f + '.o')
except:
pass
- compiler_flags = ['-emit-llvm']
- if not f.endswith('.c'):
- compiler_flags = compiler_flags + ['-std=c++03']
- args = [Building.COMPILER] + compiler_flags + COMPILER_OPTS + Building.COMPILER_TEST_OPTS + \
+ args = [PYTHON, EMCC] + Building.COMPILER_TEST_OPTS + \
['-I', dirname, '-I', os.path.join(dirname, 'include')] + \
map(lambda include: '-I' + include, includes) + \
['-c', f, '-o', f + '.o']
@@ -358,7 +357,8 @@ process(sys.argv[1])
build_dir = self.get_build_dir()
output_dir = self.get_dir()
- cache_name = name + cache_name_extra
+ cache_name = name + cache_name_extra + (self.env.get('EMCC_LLVM_TARGET') or '')
+
if self.library_cache is not None:
if cache and self.library_cache.get(cache_name):
print >> sys.stderr, '<load %s from cache> ' % cache_name,
@@ -455,7 +455,7 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows
if len(sys.argv) == 2 and 'ALL.' in sys.argv[1]:
ignore, test = sys.argv[1].split('.')
print 'Running all test modes on test "%s"' % test
- sys.argv = [sys.argv[0], 'default.'+test, 'o1.'+test, 'o2.'+test, 'asm1.'+test, 'asm2.'+test, 'asm2g.'+test, 's_0_0.'+test, 's_0_1.'+test, 's_1_0.'+test, 's_1_1.'+test]
+ sys.argv = [sys.argv[0], 'default.'+test, 'o1.'+test, 'o2.'+test, 'asm1.'+test, 'asm2.'+test, 'asm2g.'+test, 'asm2le32.'+test, 's_0_0.'+test, 's_0_1.'+test, 's_1_0.'+test, 's_1_1.'+test]
class T(RunnerCore): # Short name, to make it more fun to use manually on the commandline
## Does a complete test - builds, runs, checks output, etc.
@@ -506,6 +506,9 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows
output_nicerizer=output_nicerizer,
post_build=None) # post_build was already done in ll_to_js, this do_run call is just to test the output
+ def is_le32(self):
+ return 'le32-unknown-nacl' in COMPILER_OPTS or self.env.get('EMCC_LLVM_TARGET') == 'le32-unknown-nacl'
+
def test_hello_world(self):
src = '''
#include <stdio.h>
@@ -1118,6 +1121,7 @@ m_divisor is 1091269979
{
a = argc;
b = argv[1][0];
+ printf("%d,%d\n", a, b);
if (a > a + b || a > a + b + 1) {
printf("one %lld, %lld", a, b);
return 0;
@@ -1132,10 +1136,11 @@ m_divisor is 1091269979
if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2')
src = r'''
+ #include <stdint.h>
#include <stdio.h>
int main(int argc, char ** argv){
int y=-133;
- __int64_t x= ((__int64_t)((short)(y)))*(100 + argc);
+ int64_t x= ((int64_t)((short)(y)))*(100 + argc);
if(x>0)
printf(">0\n");
else
@@ -1198,9 +1203,9 @@ m_divisor is 1091269979
// from cube2, zlib licensed
- #define N (624)
- #define M (397)
- #define K (0x9908B0DFU)
+ #define N (624)
+ #define M (397)
+ #define K (0x9908B0DFU)
static uint state[N];
static int next = N;
@@ -1378,7 +1383,7 @@ c5,de,15,8a
#include <string>
#include <sstream>
- typedef unsigned long long quint64;
+ typedef unsigned long long quint64;
using namespace std;
@@ -1406,14 +1411,14 @@ c5,de,15,8a
printf("1\n");
s >> hex >> int64bitInt;
printf("2\n");
-
+
stringstream out;
out << hex << qbswap(int64bitInt);
-
+
cout << out.str() << endl;
cout << hex << int64bitInt << endl;
cout << string64bitInt << endl;
-
+
if (out.str() != "bbccddeeff3344")
{
cout << "Failed!" << endl;
@@ -1455,7 +1460,7 @@ Succeeded!
# A good test of i64 math
if Settings.USE_TYPED_ARRAYS != 2: return self.skip('requires ta2 C-style memory aliasing')
self.do_run('', 'Usage: hashstring <seed>',
- libraries=self.get_library('cube2hash', ['cube2hash.bc'], configure=None),
+ libraries=self.get_library('cube2hash', ['cube2hash.bc'], configure=None),
includes=[path_from_root('tests', 'cube2hash')])
for text, output in [('fleefl', '892BDB6FD3F62E863D63DA55851700FDE3ACF30204798CE9'),
@@ -1498,7 +1503,11 @@ Succeeded!
'''
# TODO: A version of this with int64s as well
- self.do_run(src, '*12 : 1 : 12\n328157500735811.0,23,416012775903557.0,99\n')
+
+ if self.is_le32():
+ return self.skip('LLVM marks the reads of s as fully aligned, making this test invalid')
+ else:
+ self.do_run(src, '*12 : 1 : 12\n328157500735811.0,23,416012775903557.0,99\n')
return # TODO: continue to the next part here
@@ -1532,6 +1541,62 @@ Succeeded!
except Exception, e:
assert 'must be aligned' in str(e), e # expected to fail without emulation
+ def test_align64(self):
+ src = r'''
+ #include <stdio.h>
+
+ // inspired by poppler
+
+ enum Type {
+ A = 10,
+ B = 20
+ };
+
+ struct Object {
+ Type type;
+ union {
+ int intg;
+ double real;
+ char *name;
+ };
+ };
+
+ struct Principal {
+ double x;
+ Object a;
+ double y;
+ };
+
+ int main(int argc, char **argv)
+ {
+ int base = argc-1;
+ Object *o = NULL;
+ printf("%d,%d\n", sizeof(Object), sizeof(Principal));
+ printf("%d,%d,%d,%d\n", (int)&o[base].type, (int)&o[base].intg, (int)&o[base].real, (int)&o[base].name);
+ printf("%d,%d,%d,%d\n", (int)&o[base+1].type, (int)&o[base+1].intg, (int)&o[base+1].real, (int)&o[base+1].name);
+ Principal p, q;
+ p.x = p.y = q.x = q.y = 0;
+ p.a.type = A;
+ p.a.real = 123.456;
+ *(&q.a) = p.a;
+ printf("%.2f,%d,%.2f,%.2f : %.2f,%d,%.2f,%.2f\n", p.x, p.a.type, p.a.real, p.y, q.x, q.a.type, q.a.real, q.y);
+ return 0;
+ }
+ '''
+
+ if self.is_le32():
+ self.do_run(src, '''16,32
+0,8,8,8
+16,24,24,24
+0.00,10,123.46,0.00 : 0.00,10,123.46,0.00
+''')
+ else:
+ self.do_run(src, '''12,28
+0,4,4,4
+12,16,16,16
+0.00,10,123.46,0.00 : 0.00,10,123.46,0.00
+''')
+
def test_unsigned(self):
Settings.CORRECT_SIGNS = 1 # We test for exactly this sort of thing here
Settings.CHECK_SIGNS = 0
@@ -1752,10 +1817,10 @@ Succeeded!
int main()
{
printf("*%.2f,%.2f,%d", M_PI, -M_PI, (1/0.0) > 1e300); // could end up as infinity, or just a very very big number
- printf(",%d", finite(NAN) != 0);
- printf(",%d", finite(INFINITY) != 0);
- printf(",%d", finite(-INFINITY) != 0);
- printf(",%d", finite(12.3) != 0);
+ printf(",%d", isfinite(NAN) != 0);
+ printf(",%d", isfinite(INFINITY) != 0);
+ printf(",%d", isfinite(-INFINITY) != 0);
+ printf(",%d", isfinite(12.3) != 0);
printf(",%d", isinf(NAN) != 0);
printf(",%d", isinf(INFINITY) != 0);
printf(",%d", isinf(-INFINITY) != 0);
@@ -2238,7 +2303,7 @@ cat |umber one top notchfi FI FO FUM WHEN WHERE WHY HOW WHO|''', ['wowie', 'too'
total += c->value;
c = c->next;
} while (c != chunk);
-
+
printf("*%d,%d*\\n", total, b.next);
// NULL *is* 0, in C/C++. No JS null! (null == 0 is false, etc.)
@@ -2330,19 +2395,19 @@ cat |umber one top notchfi FI FO FUM WHEN WHERE WHY HOW WHO|''', ['wowie', 'too'
src = r'''
#include <stdio.h>
#include <setjmp.h>
-
+
static jmp_buf buf;
-
+
void second(void) {
printf("second\n"); // prints
longjmp(buf,1); // jumps back to where setjmp was called - making setjmp now return 1
}
-
+
void first(void) {
second();
printf("first\n"); // does not print
}
-
+
int main() {
volatile int x = 0;
if ( ! setjmp(buf) ) {
@@ -2351,7 +2416,7 @@ cat |umber one top notchfi FI FO FUM WHEN WHERE WHY HOW WHO|''', ['wowie', 'too'
} else { // when longjmp jumps back, setjmp returns 1
printf("main: %d\n", x); // prints
}
-
+
return 0;
}
'''
@@ -2510,7 +2575,7 @@ Exception execution path of first function! 1
src = r'''
#include <stdio.h>
#include <setjmp.h>
-
+
static jmp_buf buf;
void (*fp)() = NULL;
@@ -2519,12 +2584,12 @@ Exception execution path of first function! 1
printf("second\n"); // prints
longjmp(buf,1); // jumps back to where setjmp was called - making setjmp now return 1
}
-
+
void first(void) {
fp();
printf("first\n"); // does not print
}
-
+
int main(int argc, char **argv) {
fp = argc == 200 ? NULL : second;
@@ -2535,7 +2600,7 @@ Exception execution path of first function! 1
} else { // when longjmp jumps back, setjmp returns 1
printf("main: %d\n", x); // prints
}
-
+
return 0;
}
'''
@@ -2547,15 +2612,15 @@ Exception execution path of first function! 1
src = r'''
#include <stdio.h>
#include <setjmp.h>
-
+
static jmp_buf buf;
-
+
int main() {
volatile int x = 0;
printf("setjmp:%d\n", setjmp(buf));
x++;
printf("x:%d\n", x);
- if (x < 4) longjmp(buf, x*2);
+ if (x < 4) longjmp(buf, x*2);
return 0;
}
'''
@@ -2629,6 +2694,37 @@ back
12
''')
+ def test_longjmp_exc(self):
+ src = r'''
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <setjmp.h>
+ #include <emscripten.h>
+
+ jmp_buf abortframe;
+
+ void dostuff(int a) {
+ printf("pre\n");
+ if (a != 42) emscripten_run_script("waka_waka()"); // this should fail, and never reach "never"
+ printf("never\n");
+
+ if (a == 100) {
+ longjmp (abortframe, -1);
+ }
+
+ if (setjmp(abortframe)) {
+ printf("got 100");
+ }
+ }
+
+ int main(int argc, char **argv) {
+ dostuff(argc);
+ exit(1);
+ return 1;
+ }
+ '''
+ self.do_run(src, 'waka_waka');
+
def test_setjmp_many(self):
src = r'''
#include <stdio.h>
@@ -2685,7 +2781,7 @@ back
src = '''
#include <iostream>
-
+
class MyException
{
public:
@@ -2693,21 +2789,21 @@ back
MyException( const MyException & ) { std::cout << "Copy..."; }
~MyException(){ std::cout << "Destruct..."; }
};
-
+
int function()
{
std::cout << "Throw...";
throw MyException();
}
-
+
int function2()
{
return function();
}
-
+
int main()
{
- try
+ try
{
function2();
}
@@ -2715,8 +2811,8 @@ back
{
std::cout << "Catched...";
}
-
- try
+
+ try
{
function2();
}
@@ -2724,11 +2820,11 @@ back
{
std::cout << "Catched...";
}
-
+
return 0;
}
'''
-
+
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
@@ -2741,7 +2837,7 @@ back
src = '''
#include <stdio.h>
-
+
void thrower() {
printf("infunc...");
throw(99);
@@ -3239,6 +3335,36 @@ Exiting setjmp function, level: 0, prev_jmp: -1
'''
self.do_run(src, '*0x1*')
+ def test_funcptr_namecollide(self):
+ src = r'''
+ #include <stdio.h>
+
+ void do_call(void (*puts)(const char *), const char *str);
+
+ void do_print(const char *str) {
+ if (!str) do_call(NULL, "delusion");
+ if ((int)str == -1) do_print(str+10);
+ puts("====");
+ puts(str);
+ puts("====");
+ }
+
+ void do_call(void (*puts)(const char *), const char *str) {
+ if (!str) do_print("confusion");
+ if ((int)str == -1) do_call(NULL, str-10);
+ (*puts)(str);
+ }
+
+ int main(int argc, char **argv)
+ {
+ for (int i = 0; i < argc; i++) {
+ do_call(i != 10 ? do_print : NULL, i != 15 ? "waka waka" : NULL);
+ }
+ return 0;
+ }
+ '''
+ self.do_run(src, 'waka', force_c=True)
+
def test_emptyclass(self):
if self.emcc_args is None: return self.skip('requires emcc')
src = '''
@@ -3358,7 +3484,7 @@ Exiting setjmp function, level: 0, prev_jmp: -1
static char s[100]="aaaaa";
static int func(void) {
- if(s[0]!='a') return 0;
+ if(s[0]!='a') return 0;
printf("iso open %s\n", s, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001);
return 0;
}
@@ -3375,17 +3501,41 @@ Exiting setjmp function, level: 0, prev_jmp: -1
if self.emcc_args is None: return self.skip('need c99')
self.emcc_args += ['-std=c99']
src = open(path_from_root('tests', 'life.c'), 'r').read()
- self.do_run(src, '''--------
- [][][]
-[][]
- []
- []
-[][]
-
-
-
---------
-''', ['8', '8', '25000'], force_c=True)
+ self.do_run(src, '''--------------------------------
+[] [] [][][]
+ [] [] [] [][] [] [] []
+[] [][] [][] [][][] []
+ [] [] [] [] [][] [] []
+ [] [][] [] [] [] [] [][][][]
+ [][] [][] [] [][][] [] []
+ [] [][] [][] [][] [][][]
+ [][] [][][] [] []
+ [][] [][] []
+ [][][]
+ []
+
+
+
+
+ [][][]
+ [] [][] [][]
+ [][] [] [][] [][]
+ [][] [][]
+ []
+ [][]
+ [][] []
+[] [][] []
+ [][][] []
+ [] [][]
+[] [] []
+ []
+[] [] []
+ [][][]
+
+ []
+ [][][] []
+--------------------------------
+''', ['2'], force_c=True)
def test_array2(self):
src = '''
@@ -3593,7 +3743,10 @@ Exiting setjmp function, level: 0, prev_jmp: -1
# Compressed memory. Note that sizeof() does give the fat sizes, however!
self.do_run(src, '*0,0,0,1,2,3,4,5*\n*1,0,0*\n*0*\n0:1,1\n1:1,1\n2:1,1\n*12,20,5*')
else:
- self.do_run(src, '*0,0,0,4,8,12,16,20*\n*1,0,0*\n*0*\n0:1,1\n1:1,1\n2:1,1\n*12,20,20*')
+ if self.is_le32():
+ self.do_run(src, '*0,0,0,4,8,16,20,24*\n*1,0,0*\n*0*\n0:1,1\n1:1,1\n2:1,1\n*16,24,24*')
+ else:
+ self.do_run(src, '*0,0,0,4,8,12,16,20*\n*1,0,0*\n*0*\n0:1,1\n1:1,1\n2:1,1\n*12,20,20*')
def test_ptrtoint(self):
if self.emcc_args is None: return self.skip('requires emcc')
@@ -3844,7 +3997,7 @@ def process(filename):
def test_cxx03_do_run(self):
src = '''
#include <stdio.h>
-
+
#if __cplusplus != 199711L
#error By default, if no -std is specified, emscripten should be compiling with -std=c++03!
#endif
@@ -3916,7 +4069,7 @@ def process(filename):
#pragma pack(push,1)
typedef struct header
- {
+ {
unsigned char id;
unsigned short colour;
unsigned char desc;
@@ -3924,7 +4077,7 @@ def process(filename):
#pragma pack(pop)
typedef struct fatheader
- {
+ {
unsigned char id;
unsigned short colour;
unsigned char desc;
@@ -3960,7 +4113,7 @@ def process(filename):
// Try it with copying
va_list tempva;
- __va_copy(tempva, v);
+ va_copy(tempva, v);
vsnprintf(d, 20, s, tempva);
puts(d);
@@ -4016,6 +4169,7 @@ def process(filename):
def test_varargs_byval(self):
if Settings.USE_TYPED_ARRAYS != 2: return self.skip('FIXME: Add support for this')
+ if self.is_le32(): return self.skip('clang cannot compile this code with that target yet')
src = r'''
#include <stdio.h>
@@ -4190,7 +4344,10 @@ The current type of b is: 9
output = Popen([PYTHON, EMCC, all_name], stderr=PIPE).communicate()
# Check for warning in the generated code
generated = open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read()
- assert 'Casting a function pointer type to another with a different number of arguments' in output[1], 'Missing expected warning'
+ if 'i386-pc-linux-gnu' in COMPILER_OPTS:
+ assert 'Casting a function pointer type to another with a different number of arguments' in output[1], 'Missing expected warning'
+ else:
+ print >> sys.stderr, 'skipping C/C++ conventions warning check, since not i386-pc-linux-gnu'
def test_stdlibs(self):
if self.emcc_args is None: return self.skip('requires emcc')
@@ -4269,14 +4426,14 @@ The current type of b is: 9
src = r'''
#include <stdio.h>
#include <stdlib.h>
-
+
static void cleanA() {
printf("A");
}
static void cleanB() {
printf("B");
}
-
+
int main() {
atexit(cleanA);
atexit(cleanB);
@@ -4810,9 +4967,9 @@ The current type of b is: 9
chain *c = NULL;
printf("*%d,%d,%d,%d,%d,%d|%d,%d,%d,%d,%d,%d,%d,%d|%d,%d,%d,%d,%d,%d,%d,%d,%d,%d*\\n",
sizeof(base),
- int(&(b->x)), int(&(b->y)), int(&(b->a)), int(&(b->b)), int(&(b->c)),
+ int(&(b->x)), int(&(b->y)), int(&(b->a)), int(&(b->b)), int(&(b->c)),
sizeof(hashtableentry),
- int(&(e->key)), int(&(e->data)), int(&(e->data.x)), int(&(e->data.y)), int(&(e->data.a)), int(&(e->data.b)), int(&(e->data.c)),
+ int(&(e->key)), int(&(e->data)), int(&(e->data.x)), int(&(e->data.y)), int(&(e->data.a)), int(&(e->data.b)), int(&(e->data.c)),
sizeof(hashset::chain),
int(&(c->elem)), int(&(c->next)), int(&(c->elem.key)), int(&(c->elem.data)), int(&(c->elem.data.x)), int(&(c->elem.data.y)), int(&(c->elem.data.a)), int(&(c->elem.data.b)), int(&(c->elem.data.c))
);
@@ -5425,7 +5582,7 @@ at function.:blag
src = open(path_from_root('tests', 'parseInt', 'src.c'), 'r').read()
expected = open(path_from_root('tests', 'parseInt', 'output.txt'), 'r').read()
self.do_run(src, expected)
-
+
def test_transtrcase(self):
src = '''
#include <stdio.h>
@@ -5565,7 +5722,7 @@ at function.:blag
}
'''
self.do_run(src, '22 : me and myself 25 1.34\n21 waka 95\n')
-
+
def test_perrar(self):
src = r'''
#include <sys/types.h>
@@ -5869,20 +6026,21 @@ Pass: 0.000012 0.000012''')
return 0;
}
'''
- self.do_run(src, '''0:173,16 1:16,173 2:183,173 3:17,287 4:98,123''')
+ self.do_run(src, '''0:173,16 1:16,173 2:183,173 3:17,287 4:98,123''')
def test_sscanf_3(self):
# i64
if not Settings.USE_TYPED_ARRAYS == 2: return self.skip('64-bit sscanf only supported in ta2')
src = r'''
+ #include <stdint.h>
#include <stdio.h>
int main(){
-
+
int64_t s, m, l;
printf("%d\n", sscanf("123 1073741823 1125899906842620", "%lld %lld %lld", &s, &m, &l));
printf("%lld,%lld,%lld\n", s, m, l);
-
+
int64_t negS, negM, negL;
printf("%d\n", sscanf("-123 -1073741823 -1125899906842620", "%lld %lld %lld", &negS, &negM, &negL));
printf("%lld,%lld,%lld\n", negS, negM, negL);
@@ -5890,8 +6048,8 @@ Pass: 0.000012 0.000012''')
return 0;
}
'''
-
- self.do_run(src, '3\n123,1073741823,1125899906842620\n' +
+
+ self.do_run(src, '3\n123,1073741823,1125899906842620\n' +
'3\n-123,-1073741823,-1125899906842620\n')
def test_sscanf_4(self):
@@ -5934,6 +6092,7 @@ Pass: 0.000012 0.000012''')
if Settings.USE_TYPED_ARRAYS != 2: return self.skip("need ta2 for full i64")
src = r'''
+ #include <stdint.h>
#include <stdio.h>
int main(){
@@ -6482,7 +6641,7 @@ def process(filename):
'''
self.do_run(src, "some string constant")
-
+
def test_istream(self):
if self.emcc_args is None: return self.skip('requires libcxx')
@@ -6490,15 +6649,15 @@ def process(filename):
#include <string>
#include <sstream>
#include <iostream>
-
+
int main()
{
std::string mystring("1 2 3");
std::istringstream is(mystring);
int one, two, three;
-
+
is >> one >> two >> three;
-
+
printf( "%i %i %i", one, two, three );
}
'''
@@ -6520,19 +6679,19 @@ def process(filename):
src = '''
#include <dirent.h>
#include <stdio.h>
-
+
int main()
{
DIR * dir;
dirent * entity;
-
+
dir = opendir( "test" );
-
+
while( ( entity = readdir( dir ) ) )
{
printf( "%s is a %s\\n", entity->d_name, entity->d_type & DT_DIR ? "directory" : "file" );
}
-
+
return 0;
}
@@ -7051,7 +7210,7 @@ int main(int argc, char **argv) {
int main ( int argc, char *argv[] )
{
- std::vector<S> ar;
+ std::vector<S> ar;
S s;
s.a = 789;
@@ -7130,7 +7289,7 @@ extern "C" {
int main()
{
const char* jsonString = "{\\"key\\": \\"value\\",\\"array\\": [\\"array_item1\\",\\"array_item2\\",\\"array_item3\\"],\\"dict\\":{\\"number\\": 3,\\"float\\": 2.2}}";
-
+
json_error_t error;
json_t *root = json_loadb(jsonString, strlen(jsonString), 0, &error);
@@ -7145,7 +7304,7 @@ extern "C" {
}
printf("%s\\n", json_string_value(json_object_get(root, "key")));
-
+
json_t *array = json_object_get(root, "array");
if(!array) {
printf("Node `array` is `null`.");
@@ -7171,7 +7330,7 @@ extern "C" {
json_t *numberNode = json_object_get(dict, "number");
json_t *floatNode = json_object_get(dict, "float");
-
+
if(!numberNode || !json_is_number(numberNode) ||
!floatNode || !json_is_real(floatNode))
return 0;
@@ -7261,7 +7420,7 @@ extern "C" {
def test_dlmalloc_partial(self):
if self.emcc_args is None: return self.skip('only emcc will link in dlmalloc')
# present part of the symbols of dlmalloc, not all
- src = open(path_from_root('tests', 'new.cpp')).read().replace('{{{ NEW }}}', 'new int').replace('{{{ DELETE }}}', 'delete') + '''
+ src = open(path_from_root('tests', 'new.cpp')).read().replace('{{{ NEW }}}', 'new int').replace('{{{ DELETE }}}', 'delete') + '''
void *
operator new(size_t size)
{
@@ -7272,7 +7431,7 @@ operator new(size_t size)
self.do_run(src, 'new 4!\n*1,0*')
def test_dlmalloc_partial_2(self):
- if self.emcc_args is None or 'SAFE_HEAP' in str(self.emcc_args): return self.skip('only emcc will link in dlmalloc, and we do unsafe stuff')
+ if self.emcc_args is None or 'SAFE_HEAP' in str(self.emcc_args) or 'CHECK_HEAP_ALIGN' in str(self.emcc_args): return self.skip('only emcc will link in dlmalloc, and we do unsafe stuff')
# present part of the symbols of dlmalloc, not all. malloc is harder to link than new which is weak.
src = r'''
#include <stdio.h>
@@ -7393,7 +7552,7 @@ void*:16
struct DATA
{
int value;
-
+
DATA()
{
value = 0;
@@ -7403,7 +7562,7 @@ void*:16
DATA & GetData()
{
static DATA data;
-
+
return data;
}
@@ -7437,7 +7596,7 @@ void*:16
#include <stdio.h>
#include <sys/mman.h>
#include <assert.h>
-
+
int main(int argc, char *argv[]) {
for (int i = 0; i < 10; i++) {
int* map = (int*)mmap(0, 5000, PROT_READ | PROT_WRITE,
@@ -7448,23 +7607,23 @@ void*:16
const int NUM_BYTES = 8 * 1024 * 1024;
const int NUM_INTS = NUM_BYTES / sizeof(int);
-
+
int* map = (int*)mmap(0, NUM_BYTES, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANON, -1, 0);
assert(map != MAP_FAILED);
int i;
-
+
for (i = 0; i < NUM_INTS; i++) {
map[i] = i;
}
-
+
for (i = 0; i < NUM_INTS; i++) {
assert(map[i] == i);
}
-
+
assert(munmap(map, NUM_BYTES) == 0);
-
+
printf("hello,world");
return 0;
}
@@ -7535,20 +7694,14 @@ void*:16
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')
- # Overflows in luaS_newlstr hash loop
- if self.emcc_args is None: Settings.SAFE_HEAP = 0 # Has various warnings, with copied HEAP_HISTORY values (fixed if we copy 'null' as the type)
- Settings.CORRECT_OVERFLOWS = 1
- Settings.CHECK_OVERFLOWS = 0
- Settings.CORRECT_SIGNS = 1 # Not sure why, but needed
-
- self.do_ll_run(path_from_root('tests', 'lua', 'lua.ll'),
- 'hello lua world!\n17\n1\n2\n3\n4\n7',
- args=['-e', '''print("hello lua world!");print(17);for x = 1,4 do print(x) end;print(10-3)'''],
- output_nicerizer=lambda string, err: (string + err).replace('\n\n', '\n').replace('\n\n', '\n'),
- extra_emscripten_args=['-H', 'libc/fcntl.h,libc/sys/unistd.h,poll.h,libc/math.h,libc/langinfo.h,libc/time.h'])
+ self.do_run('',
+ 'hello lua world!\n17\n1\n2\n3\n4\n7',
+ args=['-e', '''print("hello lua world!");print(17);for x = 1,4 do print(x) end;print(10-3)'''],
+ libraries=self.get_library('lua', [os.path.join('src', 'lua'), os.path.join('src', 'liblua.a')], make=['make', 'generic'], configure=None),
+ includes=[path_from_root('tests', 'lua')],
+ output_nicerizer=lambda string, err: (string + err).replace('\n\n', '\n').replace('\n\n', '\n'))
def get_freetype(self):
Settings.DEAD_FUNCTIONS += ['_inflateEnd', '_inflate', '_inflateReset', '_inflateInit2_']
@@ -7577,7 +7730,7 @@ def process(filename):
'''
# Not needed for js, but useful for debugging
- shutil.copyfile(path_from_root('tests', 'freetype', 'LiberationSansBold.ttf'), os.path.join(self.get_dir(), 'font.ttf'))
+ shutil.copyfile(path_from_root('tests', 'freetype', 'LiberationSansBold.ttf'), os.path.join(self.get_dir(), 'font.ttf'))
# Main
self.do_run(open(path_from_root('tests', 'freetype', 'main.c'), 'r').read(),
@@ -7676,7 +7829,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 Settings.ASM_JS: return self.skip('asm does not support relying on function pointers being cast to different types')
Settings.CORRECT_OVERFLOWS = 1
Settings.CORRECT_SIGNS = 1
@@ -7854,14 +8006,14 @@ def process(filename):
if self.emcc_args is None: return self.skip('requires emcc')
if Settings.QUANTUM_SIZE == 1: return self.skip('TODO: make this work')
- # Overflows in string_hash
- Settings.CORRECT_OVERFLOWS = 1
- Settings.CHECK_OVERFLOWS = 0
- if self.emcc_args is None: Settings.SAFE_HEAP = 0 # Has bitfields which are false positives. Also the PyFloat_Init tries to detect endianness.
- Settings.CORRECT_SIGNS = 1 # Not sure why, but needed
- Settings.EXPORTED_FUNCTIONS += ['_PyRun_SimpleStringFlags'] # for the demo
+ #Settings.EXPORTED_FUNCTIONS += ['_PyRun_SimpleStringFlags'] # for the demo
+
+ if self.is_le32():
+ bitcode = path_from_root('tests', 'python', 'python.le32.bc')
+ else:
+ bitcode = path_from_root('tests', 'python', 'python.small.bc')
- self.do_ll_run(path_from_root('tests', 'python', 'python.small.bc'),
+ self.do_ll_run(bitcode,
'hello python world!\n[0, 2, 4, 6]\n5\n22\n5.470000',
args=['-S', '-c' '''print "hello python world!"; print [x*2 for x in range(4)]; t=2; print 10-3-t; print (lambda x: x*2)(11); print '%f' % 5.47'''])
@@ -8329,7 +8481,7 @@ def process(filename):
script_src = '''
var sme = Module._.ScriptMe.__new__(83); // malloc(sizeof(ScriptMe)), ScriptMe::ScriptMe(sme, 83) / new ScriptMe(83) (at addr sme)
Module._.ScriptMe.mulVal(sme, 2); // ScriptMe::mulVal(sme, 2) sme.mulVal(2)
- Module.print('*' + Module._.ScriptMe.getVal(sme) + '*');
+ Module.print('*' + Module._.ScriptMe.getVal(sme) + '*');
_free(sme);
Module.print('*ok*');
'''
@@ -9097,15 +9249,24 @@ finalizing 3 (global == 0)
''')
# Generate tests for everything
- def make_run(fullname, name=-1, compiler=-1, llvm_opts=0, embetter=0, quantum_size=0, typed_arrays=0, emcc_args=None):
+ def make_run(fullname, name=-1, compiler=-1, llvm_opts=0, embetter=0, quantum_size=0, typed_arrays=0, emcc_args=None, env='{}'):
exec('''
class %s(T):
+ env = %s
+
def tearDown(self):
super(%s, self).tearDown()
-
+
+ for k, v in self.env.iteritems():
+ del os.environ[k]
+
def setUp(self):
super(%s, self).setUp()
+ for k, v in self.env.iteritems():
+ assert k not in os.environ, k + ' should not be in environment'
+ os.environ[k] = v
+
Building.COMPILER_TEST_OPTS = ['-g']
os.chdir(self.get_dir()) # Ensure the directory exists and go there
Building.COMPILER = %r
@@ -9149,7 +9310,7 @@ class %s(T):
Building.pick_llvm_opts(3)
TT = %s
-''' % (fullname, fullname, fullname, compiler, str(emcc_args), llvm_opts, embetter, quantum_size, typed_arrays, fullname))
+''' % (fullname, env, fullname, fullname, compiler, str(emcc_args), llvm_opts, embetter, quantum_size, typed_arrays, fullname))
return TT
# Make one run with the defaults
@@ -9162,9 +9323,10 @@ TT = %s
exec('o2 = make_run("o2", compiler=CLANG, emcc_args=["-O2", "-s", "ASM_JS=0", "-s", "JS_CHUNK_SIZE=1024"])')
# asm.js
- exec('asm1 = make_run("asm1", compiler=CLANG, emcc_args=["-O1"])')
+ exec('asm1 = make_run("asm1", compiler=CLANG, emcc_args=["-O1", "-s", "CHECK_HEAP_ALIGN=1"])')
exec('asm2 = make_run("asm2", compiler=CLANG, emcc_args=["-O2"])')
exec('asm2g = make_run("asm2g", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "ASSERTIONS=1", "--memory-init-file", "1"])')
+ exec('''asm2le32 = make_run("asm2le32", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "CHECK_HEAP_ALIGN=1"], env='{"EMCC_LLVM_TARGET": "le32-unknown-nacl"}')''')
# Make custom runs with various options
for compiler, quantum, embetter, typed_arrays, llvm_opts in [
@@ -9404,7 +9566,7 @@ Options that are modified or new in %s include:
output = Popen([PYTHON, compiler, 'twopart_main.o'] + args, stdout=PIPE, stderr=PIPE).communicate()
assert os.path.exists(target), '\n'.join(output)
#print '\n'.join(output)
- self.assertContained('is not a function', run_js(target, stderr=STDOUT))
+ self.assertContained('missing function', run_js(target, stderr=STDOUT))
try_delete(target)
# Combining those bc files into js should work
@@ -9457,16 +9619,16 @@ f.close()
cmake_outputs = ['hello_world.js', 'hello_world_gles.html']
for i in range(0, 2):
for configuration in ['Debug', 'Release']:
-
+
# Create a temp workspace folder
cmakelistsdir = path_from_root('t