diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/cases/gepaddoverflow.ll | 37 | ||||
-rw-r--r-- | tests/cases/gepaddoverflow.txt | 1 | ||||
-rwxr-xr-x | tests/runner.py | 2 | ||||
-rw-r--r-- | tests/test_benchmark.py | 38 | ||||
-rw-r--r-- | tests/test_browser.py | 27 | ||||
-rw-r--r-- | tests/test_core.py | 15 | ||||
-rw-r--r-- | tests/test_other.py | 1 | ||||
-rw-r--r-- | tests/uuid/test.c | 69 |
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); +} + |