diff options
-rw-r--r-- | cmake/Platform/Emscripten.cmake | 7 | ||||
-rw-r--r-- | emscripten-version.txt | 2 | ||||
-rw-r--r-- | src/shell.html | 11 | ||||
-rw-r--r-- | src/shell_minimal.html | 11 | ||||
-rw-r--r-- | tests/cmake/target_html/CMakeLists.txt | 32 | ||||
-rw-r--r-- | tests/core/test_atomic_cxx.cpp | 50 | ||||
-rw-r--r-- | tests/core/test_atomic_cxx.txt | 64 | ||||
-rw-r--r-- | tests/test_core.py | 3 | ||||
-rw-r--r-- | tests/test_other.py | 12 | ||||
-rwxr-xr-x | tests/traverse.py | 33 | ||||
-rwxr-xr-x | tools/traverse.py | 50 |
11 files changed, 177 insertions, 98 deletions
diff --git a/cmake/Platform/Emscripten.cmake b/cmake/Platform/Emscripten.cmake index 7d86c467..f9d8c773 100644 --- a/cmake/Platform/Emscripten.cmake +++ b/cmake/Platform/Emscripten.cmake @@ -66,11 +66,11 @@ if ("${CMAKE_CXX_COMPILER}" STREQUAL "") endif() if ("${CMAKE_AR}" STREQUAL "") - set(CMAKE_AR "${EMSCRIPTEN_ROOT_PATH}/emar${EMCC_SUFFIX}") + set(CMAKE_AR "${EMSCRIPTEN_ROOT_PATH}/emar${EMCC_SUFFIX}" CACHE FILEPATH "Emscripten ar") endif() if ("${CMAKE_RANLIB}" STREQUAL "") - set(CMAKE_RANLIB "${EMSCRIPTEN_ROOT_PATH}/emranlib${EMCC_SUFFIX}") + set(CMAKE_RANLIB "${EMSCRIPTEN_ROOT_PATH}/emranlib${EMCC_SUFFIX}" CACHE FILEPATH "Emscripten ranlib") endif() # Don't do compiler autodetection, since we are cross-compiling. @@ -113,8 +113,7 @@ set(CMAKE_CXX_ARCHIVE_APPEND "${CMAKE_AR} r <TARGET> ${CMAKE_START_TEMP_FILE} <L set(CMAKE_C_ARCHIVE_APPEND "${CMAKE_AR} r <TARGET> ${CMAKE_START_TEMP_FILE} <LINK_FLAGS> <OBJECTS>${CMAKE_END_TEMP_FILE}") # Set a global EMSCRIPTEN variable that can be used in client CMakeLists.txt to detect when building using Emscripten. -# There seems to be some kind of bug with CMake, so you might need to define this manually on the command line with "-DEMSCRIPTEN=1". -set(EMSCRIPTEN 1) +set(EMSCRIPTEN 1 CACHE BOOL "If true, we are targeting Emscripten output.") # We are cross-compiling, so unset the common CMake variables that represent the target platform. Leave UNIX define enabled, since Emscripten # mimics a Linux environment. diff --git a/emscripten-version.txt b/emscripten-version.txt index 3166fbaa..226e95b7 100644 --- a/emscripten-version.txt +++ b/emscripten-version.txt @@ -1,2 +1,2 @@ -1.14.1 +1.15.0 diff --git a/src/shell.html b/src/shell.html index cbf8c0d8..226f12b9 100644 --- a/src/shell.html +++ b/src/shell.html @@ -1222,7 +1222,7 @@ postRun: [], print: (function() { var element = document.getElementById('output'); - element.value = ''; // clear browser cache + if (element) element.value = ''; // clear browser cache return function(text) { text = Array.prototype.slice.call(arguments).join(' '); // These replacements are necessary if you render to raw HTML @@ -1230,8 +1230,11 @@ //text = text.replace(/</g, "<"); //text = text.replace(/>/g, ">"); //text = text.replace('\n', '<br>', 'g'); - element.value += text + "\n"; - element.scrollTop = element.scrollHeight; // focus on bottom + console.log(text); + if (element) { + element.value += text + "\n"; + element.scrollTop = element.scrollHeight; // focus on bottom + } }; })(), printErr: function(text) { @@ -1239,7 +1242,7 @@ if (0) { // XXX disabled for safety typeof dump == 'function') { dump(text + '\n'); // fast, straight to the real console } else { - console.log(text); + console.error(text); } }, canvas: document.getElementById('canvas'), diff --git a/src/shell_minimal.html b/src/shell_minimal.html index 7a3a8d08..6f483719 100644 --- a/src/shell_minimal.html +++ b/src/shell_minimal.html @@ -78,7 +78,7 @@ postRun: [], print: (function() { var element = document.getElementById('output'); - element.value = ''; // clear browser cache + if (element) element.value = ''; // clear browser cache return function(text) { text = Array.prototype.slice.call(arguments).join(' '); // These replacements are necessary if you render to raw HTML @@ -86,8 +86,11 @@ //text = text.replace(/</g, "<"); //text = text.replace(/>/g, ">"); //text = text.replace('\n', '<br>', 'g'); - element.value += text + "\n"; - element.scrollTop = element.scrollHeight; // focus on bottom + console.log(text); + if (element) { + element.value += text + "\n"; + element.scrollTop = element.scrollHeight; // focus on bottom + } }; })(), printErr: function(text) { @@ -95,7 +98,7 @@ if (0) { // XXX disabled for safety typeof dump == 'function') { dump(text + '\n'); // fast, straight to the real console } else { - console.log(text); + console.error(text); } }, canvas: document.getElementById('canvas'), diff --git a/tests/cmake/target_html/CMakeLists.txt b/tests/cmake/target_html/CMakeLists.txt index b5c69417..ce26c541 100644 --- a/tests/cmake/target_html/CMakeLists.txt +++ b/tests/cmake/target_html/CMakeLists.txt @@ -10,6 +10,38 @@ else() # Either MinSizeRel, RelWithDebInfo or Release, all which run with optimi SET(linkFlags "-O2") endif() +if (NOT CMAKE_AR OR NOT EXISTS "${CMAKE_AR}") + message(FATAL_ERROR "CMAKE_AR='${CMAKE_AR}' does not exist for Emscripten toolchain!") +endif() + +if (NOT CMAKE_RANLIB OR NOT EXISTS "${CMAKE_RANLIB}") + message(FATAL_ERROR "CMAKE_RANLIB='${CMAKE_RANLIB}' does not exist for Emscripten toolchain!") +endif() + +if (NOT CMAKE_C_COMPILER OR NOT EXISTS "${CMAKE_C_COMPILER}") + message(FATAL_ERROR "CMAKE_C_COMPILER='${CMAKE_C_COMPILER}' does not exist for Emscripten toolchain!") +endif() + +if (NOT CMAKE_CXX_COMPILER OR NOT EXISTS "${CMAKE_CXX_COMPILER}") + message(FATAL_ERROR "CMAKE_CXX_COMPILER='${CMAKE_CXX_COMPILER}' does not exist for Emscripten toolchain!") +endif() + +if (WIN32) + message(FATAL_ERROR "WIN32 should not be defined when cross-compiling!") +endif() + +if (APPLE) + message(FATAL_ERROR "APPLE should not be defined when cross-compiling!") +endif() + +if (NOT EMSCRIPTEN) + message(FATAL_ERROR "EMSCRIPTEN should be defined when cross-compiling!") +endif() + +if (NOT CMAKE_C_SIZEOF_DATA_PTR) + message(FATAL_ERROR "CMAKE_C_SIZEOF_DATA_PTR was not defined!") +endif() + SET(CMAKE_EXECUTABLE_SUFFIX ".html") add_executable(hello_world_gles ${sourceFiles}) diff --git a/tests/core/test_atomic_cxx.cpp b/tests/core/test_atomic_cxx.cpp index 8caa3bad..f78922a1 100644 --- a/tests/core/test_atomic_cxx.cpp +++ b/tests/core/test_atomic_cxx.cpp @@ -8,7 +8,7 @@ #include <atomic> #include <cstdio> -template<typename TYPE> void test(TYPE mask0, TYPE mask1, TYPE mask2) { +template<typename TYPE, typename UNSIGNED_TYPE> void test(TYPE mask0, TYPE mask1, TYPE mask2) { typedef TYPE dog; const TYPE numMemoryOrders = 6; @@ -23,95 +23,99 @@ template<typename TYPE> void test(TYPE mask0, TYPE mask1, TYPE mask2) { // test atomic<int> std::atomic<dog> atomicDog(5); - printf("atomic<int>.is_lock_free(): %s", atomicDog.is_lock_free() ? "true" : "false"); - printf("atomic<int> value: %lld\n", TYPE(atomicDog)); + printf("atomic<int>.is_lock_free(): %s\n", atomicDog.is_lock_free() ? "true" : "false"); + printf("atomic<int> value: %lld\n", (long long)TYPE(atomicDog)); // test store/load for (TYPE i = 0; i < numMemoryOrders; i++) { atomicDog.store(i, memoryOrder[i]); - printf("store/load %lld: %lld\n", i, atomicDog.load(memoryOrder[i])); + printf("store/load %lld: %lld\n", (long long)i, (long long)atomicDog.load(memoryOrder[i])); } // test exchange for (TYPE i = 0; i < numMemoryOrders; i++) { TYPE old = atomicDog.exchange(i, memoryOrder[i]); - printf("exchange %lld: old=%lld new=%lld\n", i, old, TYPE(atomicDog)); + printf("exchange %lld: old=%lld new=%lld\n", (long long)i, (long long)old, (long long)TYPE(atomicDog)); } // compare_exchange_weak for (TYPE i = 0; i < numMemoryOrders; i++) { bool success = atomicDog.compare_exchange_weak(i, i + 1, memoryOrder[i], memoryOrder[i]); - printf("compare_exchange_weak %ld: success = %s\n", i, success ? "true" : "false"); + printf("compare_exchange_weak %lld: success = %s\n", (long long)i, success ? "true" : "false"); } // compare_exchange_strong for (TYPE i = 0; i < numMemoryOrders; i++) { bool success = atomicDog.compare_exchange_strong(i, i + 1, memoryOrder[i], memoryOrder[i]); - printf("compare_exchange_strong %ld: success = %s\n", i, success ? "true" : "false"); + printf("compare_exchange_strong %lld: success = %s\n", (long long)i, success ? "true" : "false"); } // fetch_add atomicDog = 0; for (TYPE i = 0; i < numMemoryOrders; i++) { TYPE old = atomicDog.fetch_add(1, memoryOrder[i]); - printf("fetch_add %ld: old=%d new=%ld\n", i, old, TYPE(atomicDog)); + printf("fetch_add %lld: old=%lld new=%lld\n", (long long)i, (long long)old, (long long)TYPE(atomicDog)); } // fetch_sub for (TYPE i = 0; i < numMemoryOrders; i++) { TYPE old = atomicDog.fetch_sub(1, memoryOrder[i]); - printf("fetch_sub %ld: old=%d new=%ld\n", i, old, TYPE(atomicDog)); + printf("fetch_sub %lld: old=%lld new=%lld\n", (long long)i, (long long)old, (long long)TYPE(atomicDog)); } // fetch_and for (TYPE i = 0; i < numMemoryOrders; i++) { atomicDog.store(mask0, memoryOrder[i]); TYPE old = atomicDog.fetch_and((1<<i), memoryOrder[i]); - printf("fetch_and %ld: old=%lx, new=%lx\n", i, old, TYPE(atomicDog)); + printf("fetch_and %lld: old=%llx, new=%llx\n", (long long)i, (unsigned long long)UNSIGNED_TYPE(old), (unsigned long long)UNSIGNED_TYPE(atomicDog)); } // fetch_or atomicDog = 0; for (TYPE i = 0; i < numMemoryOrders; i++) { TYPE old = atomicDog.fetch_or((1<<i), memoryOrder[i]); - printf("fetch_or %ld: old=%lx, new=%lx\n", i, old, TYPE(atomicDog)); + printf("fetch_or %lld: old=%llx, new=%llx\n", (long long)i, (unsigned long long)UNSIGNED_TYPE(old), (unsigned long long)UNSIGNED_TYPE(atomicDog)); } // fetch_xor atomicDog = 0; for (int i = 0; i < numMemoryOrders; i++) { int old = atomicDog.fetch_xor((1<<i), memoryOrder[i]); - printf("fetch_xor %ld: old=%llx, new=%lx\n", i, old, TYPE(atomicDog)); + printf("fetch_xor %lld: old=%llx, new=%llx\n", (long long)i, (unsigned long long)UNSIGNED_TYPE(old), (unsigned long long)UNSIGNED_TYPE(atomicDog)); } // operator++, -- atomicDog = 0; atomicDog++; - printf("operator++: %ld\n", TYPE(atomicDog)); + printf("operator++: %lld\n", (long long)TYPE(atomicDog)); atomicDog--; - printf("operator--: %ld\n", TYPE(atomicDog)); + printf("operator--: %lld\n", (long long)TYPE(atomicDog)); // operator +=, -=, &=, |=, ^= atomicDog += 10; - printf("operator+=: %ld\n", TYPE(atomicDog)); + printf("operator+=: %lld\n", (long long)TYPE(atomicDog)); atomicDog -= 5; - printf("operator-=: %ld\n", TYPE(atomicDog)); + printf("operator-=: %lld\n", (long long)TYPE(atomicDog)); atomicDog |= mask0; - printf("operator|=: %lx\n", TYPE(atomicDog)); + printf("operator|=: %llx\n", (unsigned long long)UNSIGNED_TYPE(atomicDog)); atomicDog &= mask1; - printf("operator|=: %lx\n", TYPE(atomicDog)); + printf("operator&=: %llx\n", (unsigned long long)UNSIGNED_TYPE(atomicDog)); atomicDog ^= mask2; - printf("operator^=: %lx\n", TYPE(atomicDog)); + printf("operator^=: %llx\n", (unsigned long long)UNSIGNED_TYPE(atomicDog)); } int main() { // test 8, 16, 32 and 64-bit data types - test<char>(0xFF, 0xF0, 0x0F); - test<short>(0xFFFF, 0xF0F0, 0x0F0F); - test<int>(0xFFFFFFFF, 0xF0F0F0F0, 0x0F0F0F0F); - test<long long>(0xFFFFFFFFFFFFFFFF, 0xF0F0F0F0F0F0F0F0, 0x0F0F0F0F0F0F0F0F); + printf("\n8 bits\n\n"); + test<char, unsigned char>(0xFF, 0xF0, 0x0F); + printf("\n16 bits\n\n"); + test<short, unsigned short>(0xFFFF, 0xF0F0, 0x0F0F); + printf("\n32 bits\n\n"); + test<int, unsigned int>(0xFFFFFFFF, 0xF0F0F0F0, 0x0F0F0F0F); + printf("\n64 bits\n\n"); + test<long long, unsigned long long>(0xFFFFFFFFFFFFFFFF, 0xF0F0F0F0F0F0F0F0, 0x0F0F0F0F0F0F0F0F); // test atomic_flag (should also have memory_orders, but probably doesn't matter // to find the missing atomic functions) diff --git a/tests/core/test_atomic_cxx.txt b/tests/core/test_atomic_cxx.txt index 25baa0cb..da437b57 100644 --- a/tests/core/test_atomic_cxx.txt +++ b/tests/core/test_atomic_cxx.txt @@ -1,4 +1,8 @@ -atomic<int>.is_lock_free(): trueatomic<int> value: 5 + +8 bits + +atomic<int>.is_lock_free(): true +atomic<int> value: 5 store/load 0: 0 store/load 1: 1 store/load 2: 2 @@ -25,12 +29,12 @@ fetch_sub 2: old=4 new=3 fetch_sub 3: old=3 new=2 fetch_sub 4: old=2 new=1 fetch_sub 5: old=1 new=0 -fetch_and 0: old=ffffffff, new=1 -fetch_and 1: old=ffffffff, new=2 -fetch_and 2: old=ffffffff, new=4 -fetch_and 3: old=ffffffff, new=8 -fetch_and 4: old=ffffffff, new=10 -fetch_and 5: old=ffffffff, new=20 +fetch_and 0: old=ff, new=1 +fetch_and 1: old=ff, new=2 +fetch_and 2: old=ff, new=4 +fetch_and 3: old=ff, new=8 +fetch_and 4: old=ff, new=10 +fetch_and 5: old=ff, new=20 fetch_or 0: old=0, new=1 fetch_or 1: old=1, new=3 fetch_or 2: old=3, new=7 @@ -47,10 +51,14 @@ operator++: 1 operator--: 0 operator+=: 10 operator-=: 5 -operator|=: ffffffff -operator|=: fffffff0 -operator^=: ffffffff -atomic<int>.is_lock_free(): trueatomic<int> value: 5 +operator|=: ff +operator&=: f0 +operator^=: ff + +16 bits + +atomic<int>.is_lock_free(): true +atomic<int> value: 5 store/load 0: 0 store/load 1: 1 store/load 2: 2 @@ -77,12 +85,12 @@ fetch_sub 2: old=4 new=3 fetch_sub 3: old=3 new=2 fetch_sub 4: old=2 new=1 fetch_sub 5: old=1 new=0 -fetch_and 0: old=ffffffff, new=1 -fetch_and 1: old=ffffffff, new=2 -fetch_and 2: old=ffffffff, new=4 -fetch_and 3: old=ffffffff, new=8 -fetch_and 4: old=ffffffff, new=10 -fetch_and 5: old=ffffffff, new=20 +fetch_and 0: old=ffff, new=1 +fetch_and 1: old=ffff, new=2 +fetch_and 2: old=ffff, new=4 +fetch_and 3: old=ffff, new=8 +fetch_and 4: old=ffff, new=10 +fetch_and 5: old=ffff, new=20 fetch_or 0: old=0, new=1 fetch_or 1: old=1, new=3 fetch_or 2: old=3, new=7 @@ -99,10 +107,14 @@ operator++: 1 operator--: 0 operator+=: 10 operator-=: 5 -operator|=: ffffffff -operator|=: fffff0f0 -operator^=: ffffffff -atomic<int>.is_lock_free(): trueatomic<int> value: 5 +operator|=: ffff +operator&=: f0f0 +operator^=: ffff + +32 bits + +atomic<int>.is_lock_free(): true +atomic<int> value: 5 store/load 0: 0 store/load 1: 1 store/load 2: 2 @@ -152,9 +164,13 @@ operator--: 0 operator+=: 10 operator-=: 5 operator|=: ffffffff -operator|=: f0f0f0f0 +operator&=: f0f0f0f0 operator^=: ffffffff -atomic<int>.is_lock_free(): trueatomic<int> value: 5 + +64 bits + +atomic<int>.is_lock_free(): false +atomic<int> value: 5 store/load 0: 0 store/load 1: 1 store/load 2: 2 @@ -204,7 +220,7 @@ operator--: 0 operator+=: 10 operator-=: 5 operator|=: ffffffffffffffff -operator|=: f0f0f0f0f0f0f0f0 +operator&=: f0f0f0f0f0f0f0f0 operator^=: ffffffffffffffff atomic_flag: false done. diff --git a/tests/test_core.py b/tests/test_core.py index 1dc5066b..ab4897f8 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -4422,8 +4422,9 @@ PORT: 3979 src, output = (test_path + s for s in ('.in', '.out')) self.do_run_from_file(src, output) - def zzztest_atomic_cxx(self): + def test_atomic_cxx(self): if self.emcc_args is None: return self.skip('needs emcc') + if os.environ.get('EMCC_FAST_COMPILER') == '0': return self.skip('needs fastcomp') test_path = path_from_root('tests', 'core', 'test_atomic_cxx') src, output = (test_path + s for s in ('.cpp', '.txt')) Building.COMPILER_TEST_OPTS += ['-std=c++11'] diff --git a/tests/test_other.py b/tests/test_other.py index 16b5ab92..cdea493a 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -856,10 +856,14 @@ This pointer might make sense in another type signature: i: 0 if engine == SPIDERMONKEY_ENGINE: self.validate_asmjs(out) # zlib compression library. tests function pointers in initializers and many other things - test('zlib', '', open(path_from_root('tests', 'zlib', 'example.c'), 'r').read(), - self.get_zlib_library(), - open(path_from_root('tests', 'zlib', 'ref.txt'), 'r').read(), - args=['-I' + path_from_root('tests', 'zlib')], suffix='c') + try: + os.environ['EMCC_FORCE_STDLIBS'] = 'libcextra' + test('zlib', '', open(path_from_root('tests', 'zlib', 'example.c'), 'r').read(), + self.get_zlib_library(), + open(path_from_root('tests', 'zlib', 'ref.txt'), 'r').read(), + args=['-I' + path_from_root('tests', 'zlib')], suffix='c') + finally: + del os.environ['EMCC_FORCE_STDLIBS'] use_cmake = WINDOWS bullet_library = get_bullet_library(self, use_cmake) diff --git a/tests/traverse.py b/tests/traverse.py deleted file mode 100755 index 37809375..00000000 --- a/tests/traverse.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python2 - -''' -simple tool to run emcc and clang on testcases each in a separate subdir, as in the case of output from Moh's fuzzer -''' - -import os, sys - -__rootpath__ = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -def path_from_root(*pathelems): - return os.path.join(__rootpath__, *pathelems) -sys.path += [path_from_root('')] -import tools.shared -from tools.shared import * - -curr = os.getcwd() - -for d in os.listdir(curr): - #print d - os.chdir(curr) - if os.path.isdir(d): - os.chdir(d) - for c in os.listdir('.'): - if c.endswith('.c'): - execute([CLANG_CC, c]) - out1 = execute(['./a.out'], stdout=PIPE)[0] - execute([EMCC, c, '-O2', '--embed-file', 'input.txt']) - out2 = jsrun.run_js('a.out.js', filter(lambda x: x != '-w', SPIDERMONKEY_ENGINE), stdout=PIPE) - if out1 != out2: - print ' ', out1, - print ' ', out2, - print 'fail', d - diff --git a/tools/traverse.py b/tools/traverse.py new file mode 100755 index 00000000..05f14597 --- /dev/null +++ b/tools/traverse.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python2 + +''' +simple tool to run emcc and clang on C testcases each in a separate subdir of the current dir +''' + +import os, sys + +__rootpath__ = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +def path_from_root(*pathelems): + return os.path.join(__rootpath__, *pathelems) +sys.path += [path_from_root('')] +import tools.shared +from tools.shared import * + +curr = os.getcwd() + +for d in os.listdir(curr): + print '(' + d + ') ', + os.chdir(curr) + if os.path.isdir(d): + os.chdir(d) + for c in os.listdir('.'): + if c.endswith('.c'): + execute([EMCC, c, '-O2', '--embed-file', 'input.txt']) + js = jsrun.run_js('a.out.js', filter(lambda x: x != '-w', SPIDERMONKEY_ENGINE), stdout=PIPE) + + execute([CLANG_CC, '-m32', c]) + n1 = execute(['./a.out'], stdout=PIPE)[0] + + execute([CLANG_CC, '-m32', c, '-O2']) + n2 = execute(['./a.out'], stdout=PIPE)[0] + + execute(['gcc', c, '-m32']) + n3 = execute(['./a.out'], stdout=PIPE)[0] + + if js == n1: + print 'ok' + elif js == n2: + print 'emcc and clang -O2 both equally wrong' + elif js == n3: + print 'emcc agrees with gcc, so probably ok' + else: + print + print 'js ', js, + print 'c0 ', n1, + print 'c2 ', n2, + print 'g ', n3, + print 'fail!!!', d + |