summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/cases/floatundefinvoke_fastcomp.ll30
-rw-r--r--tests/cases/floatundefinvoke_fastcomp.txt3
-rw-r--r--tests/core/test_exceptions_white_list_empty.out0
-rw-r--r--tests/core/test_set_align.c50
-rw-r--r--tests/core/test_set_align.out8
-rw-r--r--tests/gl_teximage.c120
-rw-r--r--tests/test_browser.py3
-rw-r--r--tests/test_core.py95
-rw-r--r--tests/test_other.py20
-rw-r--r--tests/test_sanity.py2
10 files changed, 312 insertions, 19 deletions
diff --git a/tests/cases/floatundefinvoke_fastcomp.ll b/tests/cases/floatundefinvoke_fastcomp.ll
new file mode 100644
index 00000000..215506ef
--- /dev/null
+++ b/tests/cases/floatundefinvoke_fastcomp.ll
@@ -0,0 +1,30 @@
+; ModuleID = 'a.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:128-n32-S128"
+target triple = "asmjs-unknown-emscripten"
+
+@.str = private unnamed_addr constant [11 x i8] c"float: %f\0A\00", align 1
+
+define void @_Z10printFloatf(float %f) #0 {
+entry:
+ %conv = fpext float %f to double
+ %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.str, i32 0, i32 0), double %conv)
+ ret void
+}
+
+define i32 @main() #1 {
+entry:
+ tail call void @_Z10printFloatf(float 1.000000e+00)
+ call void @emscripten_preinvoke()
+ call void @_Z10printFloatf(float undef)
+ %last = call i32 @emscripten_postinvoke()
+ %lastf = sitofp i32 %last to float
+ tail call void @_Z10printFloatf(float %lastf)
+ ret i32 1
+}
+
+declare void @emscripten_preinvoke()
+declare i32 @emscripten_postinvoke()
+declare i32 @printf(i8* nocapture, ...) #1
+
+attributes #0 = { noinline nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
diff --git a/tests/cases/floatundefinvoke_fastcomp.txt b/tests/cases/floatundefinvoke_fastcomp.txt
new file mode 100644
index 00000000..5e19391e
--- /dev/null
+++ b/tests/cases/floatundefinvoke_fastcomp.txt
@@ -0,0 +1,3 @@
+float: 1.000000
+float: 0.000000
+float: 0.000000
diff --git a/tests/core/test_exceptions_white_list_empty.out b/tests/core/test_exceptions_white_list_empty.out
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/core/test_exceptions_white_list_empty.out
diff --git a/tests/core/test_set_align.c b/tests/core/test_set_align.c
new file mode 100644
index 00000000..26158ef4
--- /dev/null
+++ b/tests/core/test_set_align.c
@@ -0,0 +1,50 @@
+
+#include <stdio.h>
+#include <emscripten.h>
+
+volatile char data[16];
+
+__attribute__((noinline)) void *get_aligned(int align)
+{
+ char *ptr = (char*)(((int)(data + 7)) & ~7); // Make 8-byte aligned
+ ptr += align; // Now 'align' aligned
+ return (void*)ptr;
+}
+
+int main()
+{
+ emscripten_align4_double *d4 = (emscripten_align4_double*)get_aligned(4);
+ *d4 = 17.0;
+ printf("addr: %d, value: %f\n", ((int)d4) % 8, *d4);
+
+ emscripten_align2_double *d2 = (emscripten_align2_double*)get_aligned(2);
+ *d2 = 18.0;
+ printf("addr: %d, value: %f\n", ((int)d2) % 8, *d2);
+
+ emscripten_align1_double *d1 = (emscripten_align1_double*)get_aligned(1);
+ *d1 = 19.0;
+ printf("addr: %d, value: %f\n", ((int)d1) % 8, *d1);
+
+ emscripten_align2_float *f2 = (emscripten_align2_float*)get_aligned(2);
+ *f2 = 20.0;
+ printf("addr: %d, value: %f\n", ((int)f2) % 4, *f2);
+
+ emscripten_align1_float *f1 = (emscripten_align1_float*)get_aligned(1);
+ *f1 = 21.0;
+ printf("addr: %d, value: %f\n", ((int)f1) % 4, *f1);
+
+ emscripten_align2_int *i2 = (emscripten_align2_int*)get_aligned(2);
+ *i2 = 22;
+ printf("addr: %d, value: %d\n", ((int)i2) % 4, *i2);
+
+ emscripten_align1_int *i1 = (emscripten_align1_int*)get_aligned(1);
+ *i1 = 23;
+ printf("addr: %d, value: %d\n", ((int)i1) % 4, *i1);
+
+ emscripten_align1_short *s1 = (emscripten_align1_short*)get_aligned(1);
+ *s1 = 24;
+ printf("addr: %d, value: %d\n", ((int)s1) % 4, (int)*s1);
+
+ return 0;
+}
+
diff --git a/tests/core/test_set_align.out b/tests/core/test_set_align.out
new file mode 100644
index 00000000..55e377b0
--- /dev/null
+++ b/tests/core/test_set_align.out
@@ -0,0 +1,8 @@
+addr: 4, value: 17.000000
+addr: 2, value: 18.000000
+addr: 1, value: 19.000000
+addr: 2, value: 20.000000
+addr: 1, value: 21.000000
+addr: 2, value: 22
+addr: 1, value: 23
+addr: 1, value: 24
diff --git a/tests/gl_teximage.c b/tests/gl_teximage.c
new file mode 100644
index 00000000..9cafce9c
--- /dev/null
+++ b/tests/gl_teximage.c
@@ -0,0 +1,120 @@
+/*
+ * GLES2 test for glTexImage2D parameters
+ *
+ * Original author: Jason Green <jason@transgaming.com>
+ *
+ */
+#include "GLES2/gl2.h"
+#include "SDL/SDL.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <emscripten.h>
+#include <unistd.h>
+
+typedef enum {
+ TEST_STATUS_SUCCESS = 0,
+ TEST_STATUS_FAILURE = 1
+} TestStatus;
+
+/* Report success or failure (1 or 0) to Emscripten's test harness. Also, exit
+ * with the given error code. */
+static void exit_with_status(TestStatus code)
+{
+#ifdef REPORT_RESULT
+ int result = (code == TEST_STATUS_SUCCESS) ? 1 : 0;
+ REPORT_RESULT();
+#endif
+
+ exit(code);
+}
+
+/* Loop over all glGetError() results until GL reports GL_NO_ERROR */
+static void clear_gl_errors()
+{
+ GLenum err;
+ do {
+ err = glGetError();
+ } while (err != GL_NO_ERROR);
+}
+
+int main(int argc, char *argv[])
+{
+ TestStatus passed = TEST_STATUS_SUCCESS;
+ SDL_Surface *screen;
+
+ if (SDL_Init(SDL_INIT_VIDEO) != 0) {
+ printf("SDL_Init failed with %s\n", SDL_GetError());
+ exit_with_status(TEST_STATUS_FAILURE);
+ }
+
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ screen = SDL_SetVideoMode(640, 480, 16, SDL_OPENGL);
+ if (!screen) {
+ printf("SDL_SetVideoMode failed with %s\n", SDL_GetError());
+ exit_with_status(TEST_STATUS_FAILURE);
+ }
+
+ GLuint texture;
+ glGenTextures(1, &texture);
+
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ // Allocate space for a 32x32 image with 4 bytes per pixel.
+ // No need to fill it with any useful information, as these tests are
+ // only designed to make sure glTexImage2D doesn't crash on unsupported
+ // formats.
+ void* pixels = malloc(4 * 32 * 32);
+ if (pixels == NULL) {
+ printf("Unable to allocate pixel data\n");
+ exit_with_status(TEST_STATUS_FAILURE);
+ }
+
+ // First, try 0xffff for the internal format - should fail
+ glTexImage2D(GL_TEXTURE_2D, 0, 0xffff, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ GLenum err = glGetError();
+ if (err == GL_NO_ERROR) {
+ printf("internal format == 0xffff succeeded, but should have failed\n");
+ passed = TEST_STATUS_FAILURE;
+ }
+ clear_gl_errors();
+
+ // Try 0xffff for the format - should fail
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, 0xffff, GL_UNSIGNED_BYTE, pixels);
+ err = glGetError();
+ if (err == GL_NO_ERROR) {
+ printf("format == 0xffff succeeded, but should have failed\n");
+ passed = TEST_STATUS_FAILURE;
+ }
+ clear_gl_errors();
+
+ // Try 0xffff for the type - should fail
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, 0xffff, pixels);
+ err = glGetError();
+ if (err == GL_NO_ERROR) {
+ printf("type == 0xffff succeeded, but should have failed\n");
+ passed = TEST_STATUS_FAILURE;
+ }
+ clear_gl_errors();
+
+ // Try GL_RGBA/GL_UNSIGNED_BYTE - should succeed
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ err = glGetError();
+ if (err != GL_NO_ERROR) {
+ printf("GL_RGBA/GL_UNSIGNED_BYTE failed with %x, but should have succeeded\n", err);
+ passed = TEST_STATUS_FAILURE;
+ }
+ clear_gl_errors();
+
+ // Clean up objects
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDeleteTextures(1, &texture);
+ free(pixels);
+
+ // 'screen' is freed implicitly by SDL_Quit()
+ SDL_Quit();
+
+ exit_with_status(passed);
+}
diff --git a/tests/test_browser.py b/tests/test_browser.py
index aedc926a..c8e07b25 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -1425,6 +1425,9 @@ keydown(100);keyup(100); // trigger the end
def test_sdlglshader(self):
self.btest('sdlglshader.c', reference='sdlglshader.png', args=['-O2', '--closure', '1', '-s', 'LEGACY_GL_EMULATION=1'])
+ def test_gl_glteximage(self):
+ self.btest('gl_teximage.c', '1')
+
def test_gl_ps(self):
# pointers and a shader
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
diff --git a/tests/test_core.py b/tests/test_core.py
index 7c317894..505a051b 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -1166,7 +1166,6 @@ 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_repeat(self):
- if os.environ.get('EMCC_FAST_COMPILER') == '0': Settings.MAX_SETJMPS = 1 # todo: do this more strict thing in fastcomp too
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)
@@ -1190,8 +1189,6 @@ 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_setjmp_many(self):
- if os.environ.get('EMCC_FAST_COMPILER') != '0': return self.skip('todo in fastcomp: make MAX_SETJMPS take effect')
-
src = r'''
#include <stdio.h>
#include <setjmp.h>
@@ -1203,9 +1200,42 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
return 0;
}
'''
- for num in [Settings.MAX_SETJMPS, Settings.MAX_SETJMPS+1]:
- print num
- self.do_run(src.replace('NUM', str(num)), '0\n' * num if num <= Settings.MAX_SETJMPS or not Settings.ASM_JS else 'build with a higher value for MAX_SETJMPS')
+ for maxx in [Settings.MAX_SETJMPS/2, Settings.MAX_SETJMPS, 2*Settings.MAX_SETJMPS]:
+ Settings.MAX_SETJMPS = maxx
+ for num in [maxx, maxx+1]:
+ print maxx, num
+ self.do_run(src.replace('NUM', str(num)), '0\n' * num if num <= Settings.MAX_SETJMPS or not Settings.ASM_JS else 'build with a higher value for MAX_SETJMPS')
+
+ def test_setjmp_many_2(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '0': return self.skip('non-fastcomp do not hit the limit.')
+
+ src = r'''
+#include <setjmp.h>
+#include <stdio.h>
+
+jmp_buf env;
+
+void luaWork(int d){
+ int x;
+ printf("d is at %d\n", d);
+
+ longjmp(env, 1);
+}
+
+int main()
+{
+ const int ITERATIONS=25;
+ for(int i = 0; i < ITERATIONS; i++){
+ if(!setjmp(env)){
+ luaWork(i);
+ }
+ }
+ return 0;
+}
+'''
+
+ self.do_run(src, r'''d is at 19
+too many setjmps in a function call, build with a higher value for MAX_SETJMPS''')
def test_exceptions(self):
if Settings.QUANTUM_SIZE == 1: return self.skip("we don't support libcxx in q1")
@@ -1317,6 +1347,33 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
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)
+ size = len(open('src.cpp.o.js').read())
+ shutil.copyfile('src.cpp.o.js', 'orig.js')
+
+ if os.environ.get('EMCC_FAST_COMPILER') != '0':
+ # check that an empty whitelist works properly (as in, same as exceptions disabled)
+ empty_output = path_from_root('tests', 'core', 'test_exceptions_white_list_empty.out')
+
+ Settings.EXCEPTION_CATCHING_WHITELIST = []
+ self.do_run_from_file(src, empty_output)
+ empty_size = len(open('src.cpp.o.js').read())
+ shutil.copyfile('src.cpp.o.js', 'empty.js')
+
+ Settings.EXCEPTION_CATCHING_WHITELIST = ['fake']
+ self.do_run_from_file(src, empty_output)
+ fake_size = len(open('src.cpp.o.js').read())
+ shutil.copyfile('src.cpp.o.js', 'fake.js')
+
+ Settings.DISABLE_EXCEPTION_CATCHING = 1
+ self.do_run_from_file(src, empty_output)
+ disabled_size = len(open('src.cpp.o.js').read())
+ shutil.copyfile('src.cpp.o.js', 'disabled.js')
+
+ assert size - empty_size > 2000, [empty_size, size] # big change when we disable entirely
+ assert size - fake_size > 2000, [fake_size, size]
+ assert empty_size == fake_size, [empty_size, fake_size]
+ assert empty_size - disabled_size < 100, [empty_size, disabled_size] # full disable removes a tiny bit more
+ assert fake_size - disabled_size < 100, [disabled_size, fake_size]
def test_exceptions_white_list_2(self):
Settings.DISABLE_EXCEPTION_CATCHING = 2
@@ -1923,6 +1980,15 @@ 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_set_align(self):
+ if self.run_name == 'slow2asm': return self.skip('FIXME in slow2asm')
+
+ Settings.SAFE_HEAP = 1
+
+ test_path = path_from_root('tests', 'core', 'test_set_align')
+ src, output = (test_path + s for s in ('.c', '.out'))
+ self.do_run_from_file(src, output)
+
def test_emscripten_api(self):
#if Settings.MICRO_OPTS or Settings.RELOOP or Building.LLVM_OPTS: return self.skip('FIXME')
@@ -2038,10 +2104,10 @@ def process(filename):
if self.emcc_args and '-O2' in self.emcc_args:
# Make sure ALLOW_MEMORY_GROWTH generates different code (should be less optimized)
- code_start = 'var TOTAL_MEMORY = '
+ code_start = 'var TOTAL_MEMORY'
fail = fail[fail.find(code_start):]
win = win[win.find(code_start):]
- assert len(fail) < len(win), 'failing code - without memory growth on - is more optimized, and smaller'
+ assert len(fail) < len(win), 'failing code - without memory growth on - is more optimized, and smaller' + str([len(fail), len(win)])
def test_ssr(self): # struct self-ref
src = '''
@@ -3214,7 +3280,7 @@ def process(filename):
break
else:
raise Exception('Could not find symbol table!')
- table = table[table.find('{'):table.rfind('}')+1]
+ table = table[table.find('{'):table.find('}')+1]
# ensure there aren't too many globals; we don't want unnamed_addr
assert table.count(',') <= 4
@@ -4664,8 +4730,7 @@ int main(void) {
if self.emcc_args is None: self.emcc_args = [] # dlmalloc auto-inclusion is only done if we use emcc
self.banned_js_engines = [NODE_JS] # slower, and fail on 64-bit
- Settings.CORRECT_SIGNS = 2
- Settings.CORRECT_SIGNS_LINES = ['src.cpp:' + str(i+4) for i in [4816, 4191, 4246, 4199, 4205, 4235, 4227]]
+ Settings.CORRECT_SIGNS = 1
Settings.TOTAL_MEMORY = 128*1024*1024 # needed with typed arrays
src = open(path_from_root('system', 'lib', 'dlmalloc.c'), 'r').read() + '\n\n\n' + open(path_from_root('tests', 'dlmalloc_test.c'), 'r').read()
@@ -5424,9 +5489,6 @@ def process(filename):
### Integration tests
def test_ccall(self):
- if self.emcc_args is not None and '-O2' in self.emcc_args:
- self.emcc_args += ['--closure', '1'] # Use closure here, to test we export things right
-
post = '''
def process(filename):
src = \'\'\'
@@ -5470,6 +5532,11 @@ def process(filename):
self.do_run_from_file(src, output, post_build=post)
+ if self.emcc_args is not None and '-O2' in self.emcc_args:
+ print 'with closure'
+ self.emcc_args += ['--closure', '1']
+ self.do_run_from_file(src, output, post_build=post)
+
def test_pgo(self):
if Settings.ASM_JS: return self.skip('PGO does not work in asm mode')
diff --git a/tests/test_other.py b/tests/test_other.py
index 5553a7b1..03859a4e 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -203,6 +203,10 @@ Options that are modified or new in %s include:
(['--typed-arrays', '1'], lambda generated: 'IHEAPU = ' in generated, 'typed arrays 1 selected'),
(['--typed-arrays', '2'], lambda generated: 'new Uint16Array' in generated and 'new Uint32Array' in generated, 'typed arrays 2 selected'),
(['--llvm-opts', '1'], lambda generated: '_puts(' in generated, 'llvm opts requested'),
+ ([], lambda generated: '// The Module object' in generated, 'without opts, comments in shell code'),
+ (['-O2'], lambda generated: '// The Module object' not in generated, 'with opts, no comments in shell code'),
+ (['-O2', '-g2'], lambda generated: '// The Module object' not in generated, 'with -g2, no comments in shell code'),
+ (['-O2', '-g3'], lambda generated: '// The Module object' in generated, 'with -g3, yes comments in shell code'),
]:
print params, text
self.clear()
@@ -1090,22 +1094,30 @@ This pointer might make sense in another type signature: i: 0
Building.emar('cr', lib_b, [b + '.o', c + '.o']) # libB.a with b.c.o,c.c.o
args = ['-s', 'ERROR_ON_UNDEFINED_SYMBOLS=1', main, '-o', 'a.out.js']
- libs = [lib_a, lib_b]
+ libs_list = [lib_a, lib_b]
# lib_a does not satisfy any symbols from main, so it will not be included,
# and there will be an unresolved symbol.
- output = Popen([PYTHON, EMCC] + args + libs, stdout=PIPE, stderr=PIPE).communicate()
+ output = Popen([PYTHON, EMCC] + args + libs_list, stdout=PIPE, stderr=PIPE).communicate()
self.assertContained('error: unresolved symbol: x', output[1])
# -Wl,--start-group and -Wl,--end-group around the libs will cause a rescan
# of lib_a after lib_b adds undefined symbol "x", so a.c.o will now be
# included (and the link will succeed).
- libs = ['-Wl,--start-group'] + libs + ['-Wl,--end-group']
+ libs = ['-Wl,--start-group'] + libs_list + ['-Wl,--end-group']
output = Popen([PYTHON, EMCC] + args + libs, stdout=PIPE, stderr=PIPE).communicate()
out_js = os.path.join(self.get_dir(), 'a.out.js')
assert os.path.exists(out_js), '\n'.join(output)
self.assertContained('result: 42', run_js(out_js))
+ # -( and -) should also work.
+ args = ['-s', 'ERROR_ON_UNDEFINED_SYMBOLS=1', main, '-o', 'a2.out.js']
+ libs = ['-Wl,-('] + libs_list + ['-Wl,-)']
+ output = Popen([PYTHON, EMCC] + args + libs, stdout=PIPE, stderr=PIPE).communicate()
+ out_js = os.path.join(self.get_dir(), 'a2.out.js')
+ assert os.path.exists(out_js), '\n'.join(output)
+ self.assertContained('result: 42', run_js(out_js))
+
def test_redundant_link(self):
lib = "int mult() { return 1; }"
lib_name = os.path.join(self.get_dir(), 'libA.c')
@@ -2210,7 +2222,7 @@ void wakaw::Cm::RasterBase<wakaw::watwat::Polocator?>(unsigned int*, unsigned in
test_js_closure_0 = open(path_from_root('tests', 'Module-exports', 'test.js')).read()
# Check that test.js compiled with --closure 0 contains "module['exports'] = Module;"
- assert "module['exports'] = Module;" in test_js_closure_0
+ assert ("module['exports'] = Module;" in test_js_closure_0) or ('module["exports"]=Module' in test_js_closure_0)
# Check that main.js (which requires test.js) completes successfully when run in node.js
# in order to check that the exports are indeed functioning correctly.
diff --git a/tests/test_sanity.py b/tests/test_sanity.py
index 3d3da523..3ebd49b6 100644
--- a/tests/test_sanity.py
+++ b/tests/test_sanity.py
@@ -240,7 +240,7 @@ class sanity(RunnerCore):
os.chmod(path_from_root('tests', 'fake', 'bin', 'llc'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
os.chmod(path_from_root('tests', 'fake', 'bin', 'clang++'), stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
try_delete(SANITY_FILE)
- output = self.check_working(EMCC, 'did not see a source tree above LLVM_DIR, could not verify version numbers match')
+ output = self.check_working(EMCC, 'did not see a source tree above the LLVM root directory')
VERSION_WARNING = 'Emscripten, llvm and clang versions do not match, this is dangerous'