aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/cases/gepaddoverflow.ll37
-rw-r--r--tests/cases/gepaddoverflow.txt1
-rwxr-xr-xtests/runner.py2
-rw-r--r--tests/test_benchmark.py38
-rw-r--r--tests/test_browser.py27
-rw-r--r--tests/test_core.py15
-rw-r--r--tests/test_other.py1
-rw-r--r--tests/uuid/test.c69
8 files changed, 168 insertions, 22 deletions
diff --git a/tests/cases/gepaddoverflow.ll b/tests/cases/gepaddoverflow.ll
new file mode 100644
index 00000000..11246c1d
--- /dev/null
+++ b/tests/cases/gepaddoverflow.ll
@@ -0,0 +1,37 @@
+; ModuleID = 'new.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"
+
+declare i32 @printf(i8* noalias, ...) nounwind
+
+@x = common global [4194304 x i8] zeroinitializer, align 4
+@.str = private constant [6 x i8] c"*%d*\0A\00", align 1
+
+define i8* @test_gep(i32 %y) nounwind readnone {
+ ; JavaScript uses double precision 64-bit floating point values, with
+ ; a 53 bit mantissa. The maximum precisely representable integer is
+ ; 9007199254740992. A number close to that limit is constructed here
+ ; for the constant part of the getelementptr instruction:
+ ; 4194304 * 2147483647 == 9007199250546688 == 9007199254740992 - 4194304
+ ; If that number appears in JavaScript source instead of being properly
+ ; limited to 32 bits, the %y parameter can be used to exceed the maximum
+ ; precisely representable integer, and make the computation inexact.
+ %test_res = getelementptr [4194304 x i8]* @x, i32 2147483647, i32 %y
+ ret i8* %test_res
+}
+
+define i32 @main() {
+ %res_0 = call i8* (i32)* @test_gep(i32 1000000000)
+ %res_1 = call i8* (i32)* @test_gep(i32 1000000001)
+ %res_0_i = ptrtoint i8* %res_0 to i32
+ %res_1_i = ptrtoint i8* %res_1 to i32
+
+ ; If getelementptr limited the constant part of the offset to 32 bits,
+ ; result will be 1. Otherwise, it cannot be 1 because the large numbers in
+ ; the calculation cannot be accurately represented by floating point math.
+ %res_diff = sub i32 %res_1_i, %res_0_i
+ %printf_res = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), i32 %res_diff)
+
+ ret i32 0
+}
+
diff --git a/tests/cases/gepaddoverflow.txt b/tests/cases/gepaddoverflow.txt
new file mode 100644
index 00000000..10fd998b
--- /dev/null
+++ b/tests/cases/gepaddoverflow.txt
@@ -0,0 +1 @@
+*1*
diff --git a/tests/runner.py b/tests/runner.py
index 494297db..7f0cbaed 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -342,7 +342,7 @@ process(sys.argv[1])
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,
+ print >> sys.stderr, '<load %s from cache> ' % cache_name
generated_libs = []
for basename, contents in self.library_cache[cache_name]:
bc_file = os.path.join(build_dir, cache_name + '_' + basename)
diff --git a/tests/test_benchmark.py b/tests/test_benchmark.py
index c4d3d216..21a47178 100644
--- a/tests/test_benchmark.py
+++ b/tests/test_benchmark.py
@@ -119,21 +119,27 @@ process(sys.argv[1])
return run_js(self.filename, engine=self.engine, args=args, stderr=PIPE, full_output=True)
# Benchmarkers
-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.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++'),
- JSBenchmarker('sm-f32', SPIDERMONKEY_ENGINE, ['-s', 'PRECISE_F32=2']),
- #JSBenchmarker('sm-f32-3.2', SPIDERMONKEY_ENGINE, ['-s', 'PRECISE_F32=2'], env={ 'LLVM': LLVM_3_2 }),
- #JSBenchmarker('sm-f32-3.3', SPIDERMONKEY_ENGINE, ['-s', 'PRECISE_F32=2'], env={ 'LLVM': LLVM_3_3 }),
- #JSBenchmarker('sm-f32-3.4', SPIDERMONKEY_ENGINE, ['-s', 'PRECISE_F32=2'], env={ 'LLVM': LLVM_3_4 }),
- #JSBenchmarker('sm-fc', SPIDERMONKEY_ENGINE, env={ 'EMCC_FAST_COMPILER': '1' }),
- #JSBenchmarker('sm-noasm', SPIDERMONKEY_ENGINE + ['--no-asmjs']),
- #JSBenchmarker('sm-noasm-f32', SPIDERMONKEY_ENGINE + ['--no-asmjs'], ['-s', 'PRECISE_F32=2']),
- #JSBenchmarker('v8', V8_ENGINE)
-]
+try:
+ benchmarkers_error = ''
+ 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.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++'),
+ JSBenchmarker('sm-f32', SPIDERMONKEY_ENGINE, ['-s', 'PRECISE_F32=2']),
+ #JSBenchmarker('sm-f32-aggro', SPIDERMONKEY_ENGINE, ['-s', 'PRECISE_F32=2', '-s', 'AGGRESSIVE_VARIABLE_ELIMINATION=1']),
+ #JSBenchmarker('sm-f32-3.2', SPIDERMONKEY_ENGINE, ['-s', 'PRECISE_F32=2'], env={ 'LLVM': LLVM_3_2 }),
+ #JSBenchmarker('sm-f32-3.3', SPIDERMONKEY_ENGINE, ['-s', 'PRECISE_F32=2'], env={ 'LLVM': LLVM_3_3 }),
+ #JSBenchmarker('sm-f32-3.4', SPIDERMONKEY_ENGINE, ['-s', 'PRECISE_F32=2'], env={ 'LLVM': LLVM_3_4 }),
+ #JSBenchmarker('sm-fc', SPIDERMONKEY_ENGINE, env={ 'EMCC_FAST_COMPILER': '1' }),
+ #JSBenchmarker('sm-noasm', SPIDERMONKEY_ENGINE + ['--no-asmjs']),
+ #JSBenchmarker('sm-noasm-f32', SPIDERMONKEY_ENGINE + ['--no-asmjs'], ['-s', 'PRECISE_F32=2']),
+ #JSBenchmarker('v8', V8_ENGINE)
+ ]
+except Exception, e:
+ benchmarkers_error = str(e)
+ benchmarkers = []
class benchmark(RunnerCore):
save_dir = True
@@ -171,6 +177,8 @@ class benchmark(RunnerCore):
Building.COMPILER_TEST_OPTS = []
def do_benchmark(self, name, src, expected_output='FAIL', args=[], emcc_args=[], native_args=[], shared_args=[], force_c=False, reps=TEST_REPS, native_exec=None, output_parser=None, args_processor=None, lib_builder=None):
+ if len(benchmarkers) == 0: raise Exception('error, no benchmarkers: ' + benchmarkers_error)
+
args = args or [DEFAULT_ARG]
if args_processor: args = args_processor(args)
diff --git a/tests/test_browser.py b/tests/test_browser.py
index 20b38bb5..c2eaabb6 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -1720,3 +1720,30 @@ keydown(100);keyup(100); // trigger the end
assert 'argv[3]: 3' in stdout
assert 'hello, world!' in stdout
assert 'hello, error stream!' in stderr
+
+ def test_uuid(self):
+ # Run with ./runner.py browser.test_uuid
+ # We run this test in Node/SPIDERMONKEY and browser environments because we try to make use of
+ # high quality crypto random number generators such as crypto.getRandomValues or randomBytes (if available).
+
+ # First run tests in Node and/or SPIDERMONKEY using run_js. Use closure compiler so we can check that
+ # require('crypto').randomBytes and window.crypto.getRandomValues doesn't get minified out.
+ Popen([PYTHON, EMCC, '-O2', '--closure', '1', path_from_root('tests', 'uuid', 'test.c'), '-o', path_from_root('tests', 'uuid', 'test.js')], stdout=PIPE, stderr=PIPE).communicate()
+
+ test_js_closure = open(path_from_root('tests', 'uuid', 'test.js')).read()
+
+ # Check that test.js compiled with --closure 1 contains ").randomBytes" and "window.crypto.getRandomValues"
+ assert ").randomBytes" in test_js_closure
+ assert "window.crypto.getRandomValues" in test_js_closure
+
+ out = run_js(path_from_root('tests', 'uuid', 'test.js'), full_output=True)
+ print out
+
+ # Tidy up files that might have been created by this test.
+ try_delete(path_from_root('tests', 'uuid', 'test.js'))
+ try_delete(path_from_root('tests', 'uuid', 'test.js.map'))
+
+ # Now run test in browser
+ self.btest(path_from_root('tests', 'uuid', 'test.c'), '1')
+
+
diff --git a/tests/test_core.py b/tests/test_core.py
index 6442f894..1dc25dce 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -4652,12 +4652,15 @@ return malloc(size);
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')
- 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'))
+ for aggro in ([0, 1] if '-O2' in self.emcc_args else [0]):
+ print aggro
+ Settings.AGGRESSIVE_VARIABLE_ELIMINATION = aggro
+ 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_']
diff --git a/tests/test_other.py b/tests/test_other.py
index 9c983f9f..f9ee2d9d 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -2209,3 +2209,4 @@ mergeInto(LibraryManager.library, {
process = Popen([PYTHON, EMCC, '-c', path_from_root('tests', 'hello_world.c'), '-o', outdir, '--default-obj-ext', 'obj'], stdout=PIPE, stderr=PIPE)
process.communicate()
assert(os.path.isfile(outdir + 'hello_world.obj'))
+
diff --git a/tests/uuid/test.c b/tests/uuid/test.c
new file mode 100644
index 00000000..dc2c6589
--- /dev/null
+++ b/tests/uuid/test.c
@@ -0,0 +1,69 @@
+#include <uuid/uuid.h>
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <emscripten.h>
+
+int isUUID(char* p, int upper) {
+ char* p1 = p;
+ do {
+ if (!(isxdigit(*p1) || (*p1 == '-')) || (upper && islower(*p1)) || (!upper && isupper(*p1))) {
+ return 0;
+ } else {
+ }
+ } while (*++p1 != 0);
+
+ if ((p[8] == '-') && (p[13] == '-') && (p[18] == '-') && (p[23] == '-')) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+int main() {
+ uuid_t uuid;
+ uuid_t uuid1;
+ uuid_t uuid2;
+ uuid_t empty_uuid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ uuid_generate(uuid);
+
+ assert(uuid_is_null(uuid) == 0);
+ assert(uuid_type(uuid) == UUID_TYPE_DCE_RANDOM);
+ assert(uuid_variant(uuid) == UUID_VARIANT_DCE);
+
+ char *generated = (char *)malloc(37*sizeof(char));
+ uuid_unparse(uuid, generated);
+ assert(isUUID(generated, 0) == 1); // Check it's a valid lower case UUID string.
+ printf("\nuuid = %s\n", generated);
+
+ assert(uuid_parse(generated, uuid1) == 0); // Check the generated UUID parses correctly into a compact UUID.
+ assert(uuid_compare(uuid1, uuid) == 0); // Compare the parsed UUID with the original.
+
+ uuid_unparse_lower(uuid, generated);
+ assert(isUUID(generated, 0) == 1); // Check it's a valid lower case UUID string.
+ printf("uuid = %s\n", generated);
+
+ uuid_unparse_upper(uuid, generated);
+ assert(isUUID(generated, 1) == 1); // Check it's a valid upper case UUID string.
+ printf("uuid = %s\n", generated);
+
+
+ uuid_copy(uuid2, uuid);
+ assert(uuid_compare(uuid2, uuid) == 0);
+
+ uuid_clear(uuid);
+ assert(uuid_compare(empty_uuid, uuid) == 0);
+
+ assert(uuid_is_null(uuid) == 1);
+
+ // The following lets the browser test exit cleanly.
+ int result = 1;
+ #if EMSCRIPTEN
+ #ifdef REPORT_RESULT
+ REPORT_RESULT();
+ #endif
+ #endif
+ exit(0);
+}
+