aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/Platform/Emscripten.cmake7
-rw-r--r--emscripten-version.txt2
-rw-r--r--src/shell.html11
-rw-r--r--src/shell_minimal.html11
-rw-r--r--tests/cmake/target_html/CMakeLists.txt32
-rw-r--r--tests/core/test_atomic_cxx.cpp50
-rw-r--r--tests/core/test_atomic_cxx.txt64
-rw-r--r--tests/test_core.py3
-rw-r--r--tests/test_other.py12
-rwxr-xr-xtests/traverse.py33
-rwxr-xr-xtools/traverse.py50
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, "&lt;");
//text = text.replace(/>/g, "&gt;");
//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, "&lt;");
//text = text.replace(/>/g, "&gt;");
//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
+