aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/Platform/Emscripten.cmake7
-rw-r--r--system/include/emscripten/bind.h22
-rw-r--r--system/include/emscripten/wire.h64
-rw-r--r--system/lib/embind/bind.cpp38
-rw-r--r--tests/cmake/target_html/CMakeLists.txt32
-rw-r--r--tests/core/test_atomic_cxx.cpp34
-rw-r--r--tests/core/test_atomic_cxx.txt52
-rw-r--r--tests/embind/embind.test.js6
-rw-r--r--tests/embind/embind_test.cpp54
-rw-r--r--tests/test_core.py2
-rw-r--r--tools/shared.py15
11 files changed, 207 insertions, 119 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/system/include/emscripten/bind.h b/system/include/emscripten/bind.h
index 872f279b..0699715c 100644
--- a/system/include/emscripten/bind.h
+++ b/system/include/emscripten/bind.h
@@ -813,7 +813,7 @@ namespace emscripten {
// NOTE: this returns the class type, not the pointer type
template<typename T>
inline TYPEID getActualType(T* ptr) {
- return reinterpret_cast<TYPEID>(&typeid(*ptr));
+ return getLightTypeID(*ptr);
};
}
@@ -851,15 +851,15 @@ namespace emscripten {
template<typename T>
struct SmartPtrIfNeeded {
template<typename U>
- SmartPtrIfNeeded(U& cls) {
- cls.template smart_ptr<T>();
+ SmartPtrIfNeeded(U& cls, const char* smartPtrName) {
+ cls.template smart_ptr<T>(smartPtrName);
}
};
template<typename T>
struct SmartPtrIfNeeded<T*> {
template<typename U>
- SmartPtrIfNeeded(U&) {
+ SmartPtrIfNeeded(U&, const char*) {
}
};
};
@@ -890,7 +890,7 @@ namespace emscripten {
}
template<typename PointerType>
- const class_& smart_ptr() const {
+ const class_& smart_ptr(const char* name) const {
using namespace internal;
typedef smart_ptr_trait<PointerType> PointerTrait;
@@ -901,7 +901,7 @@ namespace emscripten {
_embind_register_smart_ptr(
TypeID<PointerType>::get(),
TypeID<PointeeType>::get(),
- typeid(PointerType).name(),
+ name,
PointerTrait::get_sharing_policy(),
reinterpret_cast<GenericFunction>(&PointerTrait::get),
reinterpret_cast<GenericFunction>(&PointerTrait::construct_null),
@@ -933,10 +933,10 @@ namespace emscripten {
}
template<typename SmartPtr, typename... Args, typename... Policies>
- const class_& smart_ptr_constructor(SmartPtr (*factory)(Args...), Policies...) const {
+ const class_& smart_ptr_constructor(const char* smartPtrName, SmartPtr (*factory)(Args...), Policies...) const {
using namespace internal;
- smart_ptr<SmartPtr>();
+ smart_ptr<SmartPtr>(smartPtrName);
typename WithPolicies<Policies...>::template ArgTypeList<SmartPtr, Args...> args;
_embind_register_class_constructor(
@@ -949,12 +949,12 @@ namespace emscripten {
}
template<typename WrapperType, typename PointerType = WrapperType*>
- const class_& allow_subclass() const {
+ const class_& allow_subclass(const char* wrapperClassName, const char* pointerName = "<UnknownPointerName>") const {
using namespace internal;
- auto cls = class_<WrapperType, base<ClassType>>(typeid(WrapperType).name())
+ auto cls = class_<WrapperType, base<ClassType>>(wrapperClassName)
;
- SmartPtrIfNeeded<PointerType> _(cls);
+ SmartPtrIfNeeded<PointerType> _(cls, pointerName);
return class_function(
"implement",
diff --git a/system/include/emscripten/wire.h b/system/include/emscripten/wire.h
index 05b3ac33..c20e2f55 100644
--- a/system/include/emscripten/wire.h
+++ b/system/include/emscripten/wire.h
@@ -15,22 +15,66 @@
#define EMSCRIPTEN_ALWAYS_INLINE __attribute__((always_inline))
namespace emscripten {
+ #ifndef EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES
+ #define EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES 1
+ #endif
+
+
+ #if EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES
+ constexpr bool has_unbound_type_names = true;
+ #else
+ constexpr bool has_unbound_type_names = false;
+ #endif
+
namespace internal {
typedef void (*GenericFunction)();
- typedef const struct _TYPEID* TYPEID;
+ typedef const struct _TYPEID {}* TYPEID;
+
+
+ // We don't need the full std::type_info implementation. We
+ // just need a unique identifier per type and polymorphic type
+ // identification.
+
+ template<typename T>
+ struct CanonicalizedID {
+ static TYPEID get() {
+ static _TYPEID c;
+ return &c;
+ }
+ };
+
+ template<typename T>
+ struct Canonicalized {
+ typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
+ };
+
+ template<typename T>
+ struct LightTypeID {
+ static TYPEID get() {
+ typedef typename Canonicalized<T>::type C;
+ if (has_unbound_type_names || std::is_polymorphic<C>::value) {
+ return reinterpret_cast<TYPEID>(&typeid(C));
+ } else {
+ return CanonicalizedID<C>::get();
+ }
+ }
+ };
+
+ template<typename T>
+ const TYPEID getLightTypeID(const T& value) {
+ typedef typename Canonicalized<T>::type C;
+ if (has_unbound_type_names || std::is_polymorphic<C>::value) {
+ return reinterpret_cast<TYPEID>(&typeid(value));
+ } else {
+ return LightTypeID<T>::get();
+ }
+ }
- // This implementation is technically not legal, as it's not
- // required that two calls to typeid produce the same exact
- // std::type_info instance. That said, it's likely to work
- // given Emscripten compiles everything into one binary.
- // Should it not work in the future: replace TypeID with an
- // int, and store all TypeInfo we see in a map, allocating new
- // TypeIDs as we add new items to the map.
template<typename T>
struct TypeID {
static TYPEID get() {
- return reinterpret_cast<TYPEID>(&typeid(T));
+ return LightTypeID<T>::get();
}
};
@@ -53,7 +97,7 @@ namespace emscripten {
template<typename T>
struct TypeID<AllowedRawPointer<T>> {
static TYPEID get() {
- return reinterpret_cast<TYPEID>(&typeid(T*));
+ return LightTypeID<T*>::get();
}
};
diff --git a/system/lib/embind/bind.cpp b/system/lib/embind/bind.cpp
index f43d1ea1..37918050 100644
--- a/system/lib/embind/bind.cpp
+++ b/system/lib/embind/bind.cpp
@@ -14,26 +14,32 @@ using namespace emscripten;
extern "C" {
const char* __attribute__((used)) __getTypeName(const std::type_info* ti) {
+ if (has_unbound_type_names) {
#ifdef USE_CXA_DEMANGLE
- int stat;
- char* demangled = abi::__cxa_demangle(ti->name(), NULL, NULL, &stat);
- if (stat == 0 && demangled) {
- return demangled;
- }
+ int stat;
+ char* demangled = abi::__cxa_demangle(ti->name(), NULL, NULL, &stat);
+ if (stat == 0 && demangled) {
+ return demangled;
+ }
- switch (stat) {
- case -1:
- return strdup("<allocation failure>");
- case -2:
- return strdup("<invalid C++ symbol>");
- case -3:
- return strdup("<invalid argument>");
- default:
- return strdup("<unknown error>");
- }
+ switch (stat) {
+ case -1:
+ return strdup("<allocation failure>");
+ case -2:
+ return strdup("<invalid C++ symbol>");
+ case -3:
+ return strdup("<invalid argument>");
+ default:
+ return strdup("<unknown error>");
+ }
#else
- return strdup(ti->name());
+ return strdup(ti->name());
#endif
+ } else {
+ char str[80];
+ sprintf(str, "%p", ti);
+ return strdup(str);
+ }
}
}
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 e347c34a..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;
@@ -54,54 +54,54 @@ template<typename TYPE> void test(TYPE mask0, TYPE mask1, TYPE mask2) {
atomicDog = 0;
for (TYPE i = 0; i < numMemoryOrders; i++) {
TYPE old = atomicDog.fetch_add(1, memoryOrder[i]);
- printf("fetch_add %lld: old=%lld new=%lld\n", (long long)i, (long long)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 %lld: old=%lld new=%lld\n", (long long)i, (long long)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 %lld: old=%llx, new=%llx\n", (long long)i, (long long)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 %lld: old=%llx, new=%llx\n", (long long)i, (long long)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 %lld: old=%llx, new=%llx\n", (long long)i, (long long)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++: %lld\n", TYPE(atomicDog));
+ printf("operator++: %lld\n", (long long)TYPE(atomicDog));
atomicDog--;
- printf("operator--: %lld\n", TYPE(atomicDog));
+ printf("operator--: %lld\n", (long long)TYPE(atomicDog));
// operator +=, -=, &=, |=, ^=
atomicDog += 10;
- printf("operator+=: %lld\n", TYPE(atomicDog));
+ printf("operator+=: %lld\n", (long long)TYPE(atomicDog));
atomicDog -= 5;
- printf("operator-=: %lld\n", TYPE(atomicDog));
+ printf("operator-=: %lld\n", (long long)TYPE(atomicDog));
atomicDog |= mask0;
- printf("operator|=: %llx\n", TYPE(atomicDog));
+ printf("operator|=: %llx\n", (unsigned long long)UNSIGNED_TYPE(atomicDog));
atomicDog &= mask1;
- printf("operator|=: %llx\n", TYPE(atomicDog));
+ printf("operator&=: %llx\n", (unsigned long long)UNSIGNED_TYPE(atomicDog));
atomicDog ^= mask2;
- printf("operator^=: %llx\n", TYPE(atomicDog));
+ printf("operator^=: %llx\n", (unsigned long long)UNSIGNED_TYPE(atomicDog));
}
@@ -109,13 +109,13 @@ int main() {
// test 8, 16, 32 and 64-bit data types
printf("\n8 bits\n\n");
- test<char>(0xFF, 0xF0, 0x0F);
+ test<char, unsigned char>(0xFF, 0xF0, 0x0F);
printf("\n16 bits\n\n");
- test<short>(0xFFFF, 0xF0F0, 0x0F0F);
+ test<short, unsigned short>(0xFFFF, 0xF0F0, 0x0F0F);
printf("\n32 bits\n\n");
- test<int>(0xFFFFFFFF, 0xF0F0F0F0, 0x0F0F0F0F);
+ test<int, unsigned int>(0xFFFFFFFF, 0xF0F0F0F0, 0x0F0F0F0F);
printf("\n64 bits\n\n");
- test<long long>(0xFFFFFFFFFFFFFFFF, 0xF0F0F0F0F0F0F0F0, 0x0F0F0F0F0F0F0F0F);
+ 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 e0beb498..da437b57 100644
--- a/tests/core/test_atomic_cxx.txt
+++ b/tests/core/test_atomic_cxx.txt
@@ -29,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=ffffffffffffffff, new=1
-fetch_and 1: old=ffffffffffffffff, new=2
-fetch_and 2: old=ffffffffffffffff, new=4
-fetch_and 3: old=ffffffffffffffff, new=8
-fetch_and 4: old=ffffffffffffffff, new=10
-fetch_and 5: old=ffffffffffffffff, 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
@@ -51,9 +51,9 @@ operator++: 1
operator--: 0
operator+=: 10
operator-=: 5
-operator|=: ffffffff
-operator|=: fffffff0
-operator^=: ffffffff
+operator|=: ff
+operator&=: f0
+operator^=: ff
16 bits
@@ -85,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=ffffffffffffffff, new=1
-fetch_and 1: old=ffffffffffffffff, new=2
-fetch_and 2: old=ffffffffffffffff, new=4
-fetch_and 3: old=ffffffffffffffff, new=8
-fetch_and 4: old=ffffffffffffffff, new=10
-fetch_and 5: old=ffffffffffffffff, 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
@@ -107,9 +107,9 @@ operator++: 1
operator--: 0
operator+=: 10
operator-=: 5
-operator|=: ffffffff
-operator|=: fffff0f0
-operator^=: ffffffff
+operator|=: ffff
+operator&=: f0f0
+operator^=: ffff
32 bits
@@ -141,12 +141,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=ffffffffffffffff, new=1
-fetch_and 1: old=ffffffffffffffff, new=2
-fetch_and 2: old=ffffffffffffffff, new=4
-fetch_and 3: old=ffffffffffffffff, new=8
-fetch_and 4: old=ffffffffffffffff, new=10
-fetch_and 5: old=ffffffffffffffff, new=20
+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_or 0: old=0, new=1
fetch_or 1: old=1, new=3
fetch_or 2: old=3, new=7
@@ -164,7 +164,7 @@ operator--: 0
operator+=: 10
operator-=: 5
operator|=: ffffffff
-operator|=: f0f0f0f0
+operator&=: f0f0f0f0
operator^=: ffffffff
64 bits
@@ -220,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/embind/embind.test.js b/tests/embind/embind.test.js
index e2160c33..6bba4de0 100644
--- a/tests/embind/embind.test.js
+++ b/tests/embind/embind.test.js
@@ -1408,7 +1408,7 @@ module({
var e = assert.throws(cm.BindingError, function() {
cm.passThroughCustomSmartPtr(o);
});
- assert.equal('Cannot convert argument of type NSt3__110shared_ptrI20HeldByCustomSmartPtrEE to parameter type 14CustomSmartPtrI20HeldByCustomSmartPtrE', e.message);
+ assert.equal('Cannot convert argument of type shared_ptr<HeldByCustomSmartPtr> to parameter type CustomSmartPtr<HeldByCustomSmartPtr>', e.message);
o.delete();
});
@@ -1646,6 +1646,10 @@ module({
if (typeof INVOKED_FROM_EMSCRIPTEN_TEST_RUNNER === "undefined") { // TODO: Enable this to work in Emscripten runner as well!
BaseFixture.extend("unbound types", function() {
+ if (!cm.hasUnboundTypeNames) {
+ return;
+ }
+
function assertMessage(fn, message) {
var e = assert.throws(cm.UnboundTypeError, fn);
assert.equal(message, e.message);
diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp
index d299660a..1b835751 100644
--- a/tests/embind/embind_test.cpp
+++ b/tests/embind/embind_test.cpp
@@ -1150,8 +1150,8 @@ void callDifferentArguments(AbstractClass& ac, int i, double d, unsigned char f,
EMSCRIPTEN_BINDINGS(interface_tests) {
class_<AbstractClass>("AbstractClass")
- .smart_ptr<std::shared_ptr<AbstractClass>>()
- .allow_subclass<AbstractClassWrapper>()
+ .smart_ptr<std::shared_ptr<AbstractClass>>("shared_ptr<AbstractClass>")
+ .allow_subclass<AbstractClassWrapper>("AbstractClassWrapper")
.function("abstractMethod", &AbstractClass::abstractMethod)
.function("optionalMethod", &AbstractClass::optionalMethod)
;
@@ -1483,7 +1483,7 @@ EMSCRIPTEN_BINDINGS(tests) {
function("emval_test_take_and_return_TupleInStruct", &emval_test_take_and_return_TupleInStruct);
class_<ValHolder>("ValHolder")
- .smart_ptr<std::shared_ptr<ValHolder>>()
+ .smart_ptr<std::shared_ptr<ValHolder>>("std::shared_ptr<ValHolder>")
.constructor<val>()
.function("getVal", &ValHolder::getVal)
.function("getValNonConst", &ValHolder::getValNonConst)
@@ -1522,7 +1522,7 @@ EMSCRIPTEN_BINDINGS(tests) {
function("emval_test_take_and_call_functor", &emval_test_take_and_call_functor);
class_<StringHolder>("StringHolder")
- .smart_ptr<std::shared_ptr<StringHolder>>()
+ .smart_ptr<std::shared_ptr<StringHolder>>("shared_ptr<StringHolder>")
.constructor<std::string>()
.function("set", &StringHolder::set)
.function("get", &StringHolder::get)
@@ -1566,7 +1566,7 @@ EMSCRIPTEN_BINDINGS(tests) {
// register Derived before Base as a test that it's possible to
// register base classes afterwards
class_<Derived, base<Base>>("Derived")
- .smart_ptr<std::shared_ptr<Derived>>()
+ .smart_ptr<std::shared_ptr<Derived>>("shared_ptr<Derived>")
.constructor<>()
.function("getClassName", &Derived::getClassName)
.function("getMember", &Derived::getMember)
@@ -1575,7 +1575,7 @@ EMSCRIPTEN_BINDINGS(tests) {
;
class_<Base>("Base")
- .smart_ptr<std::shared_ptr<Base>>()
+ .smart_ptr<std::shared_ptr<Base>>("shared_ptr<Base")
.constructor<>()
.function("getClassName", &Base::getClassName)
.function("getClassNameFromBase", &Base::getClassNameFromBase)
@@ -1589,7 +1589,7 @@ EMSCRIPTEN_BINDINGS(tests) {
;
class_<SecondBase>("SecondBase")
- .smart_ptr<std::shared_ptr<SecondBase>>()
+ .smart_ptr<std::shared_ptr<SecondBase>>("shared_ptr<SecondBase>")
.constructor<>()
.function("getClassName", &SecondBase::getClassName)
.function("getClassNameFromSecondBase", &SecondBase::getClassNameFromSecondBase)
@@ -1612,13 +1612,13 @@ EMSCRIPTEN_BINDINGS(tests) {
;
class_<SiblingDerived>("SiblingDerived")
- .smart_ptr<std::shared_ptr<SiblingDerived>>()
+ .smart_ptr<std::shared_ptr<SiblingDerived>>("shared_ptr<SiblingDerived>")
.constructor<>()
.function("getClassName", &SiblingDerived::getClassName)
;
class_<MultiplyDerived, base<Base>>("MultiplyDerived")
- .smart_ptr<std::shared_ptr<MultiplyDerived>>()
+ .smart_ptr<std::shared_ptr<MultiplyDerived>>("shared_ptr<MultiplyDerived>")
.constructor<>()
.function("getClassName", &MultiplyDerived::getClassName)
.class_function("getInstanceCount", &MultiplyDerived::getInstanceCount)
@@ -1630,26 +1630,26 @@ EMSCRIPTEN_BINDINGS(tests) {
;
class_<DerivedThrice, base<Derived> >("DerivedThrice")
- .smart_ptr<std::shared_ptr<DerivedThrice>>()
+ .smart_ptr<std::shared_ptr<DerivedThrice>>("shared_ptr<DerivedThrice>")
.constructor<>()
.function("getClassName", &DerivedThrice::getClassName)
;
class_<PolyBase>("PolyBase")
- .smart_ptr<std::shared_ptr<PolyBase>>()
+ .smart_ptr<std::shared_ptr<PolyBase>>("shared_ptr<PolyBase>")
.constructor<>()
.function("virtualGetClassName", &PolyBase::virtualGetClassName)
.function("getClassName", &PolyBase::getClassName)
;
class_<PolySecondBase>("PolySecondBase")
- .smart_ptr<std::shared_ptr<PolySecondBase>>()
+ .smart_ptr<std::shared_ptr<PolySecondBase>>("shared_ptr<PolySecondBase>")
.constructor<>()
.function("getClassName", &PolySecondBase::getClassName)
;
class_<PolyDerived, base<PolyBase>>("PolyDerived")
- .smart_ptr<std::shared_ptr<PolyDerived>>()
+ .smart_ptr<std::shared_ptr<PolyDerived>>("shared_ptr<PolyDerived>")
.constructor<>()
.function("virtualGetClassName", &PolyDerived::virtualGetClassName)
.function("getClassName", &PolyDerived::getClassName)
@@ -1671,43 +1671,43 @@ EMSCRIPTEN_BINDINGS(tests) {
// }
class_<PolySiblingDerived, base<PolyBase>>("PolySiblingDerived")
- .smart_ptr<std::shared_ptr<PolySiblingDerived>>()
+ .smart_ptr<std::shared_ptr<PolySiblingDerived>>("shared_ptr<PolySiblingDerived>")
.constructor<>()
.function("getClassName", &PolySiblingDerived::getClassName)
;
class_<PolyMultiplyDerived, base<PolyBase>>("PolyMultiplyDerived")
- .smart_ptr<std::shared_ptr<PolyMultiplyDerived>>()
+ .smart_ptr<std::shared_ptr<PolyMultiplyDerived>>("shared_ptr<PolyMultiplyDerived>")
.constructor<>()
.function("getClassName", &PolyMultiplyDerived::getClassName)
;
class_<PolyDerivedThrice, base<PolyDerived>>("PolyDerivedThrice")
- .smart_ptr<std::shared_ptr<PolyDerivedThrice>>()
+ .smart_ptr<std::shared_ptr<PolyDerivedThrice>>("shared_ptr<PolyDerivedThrice>")
.constructor<>()
.function("getClassName", &PolyDerivedThrice::getClassName)
;
class_<PolyDiamondBase>("PolyDiamondBase")
- .smart_ptr<std::shared_ptr<PolyDiamondBase>>()
+ .smart_ptr<std::shared_ptr<PolyDiamondBase>>("shared_ptr<PolyDiamondBase>")
.constructor<>()
.function("getClassName", &PolyDiamondBase::getClassName)
;
class_<PolyDiamondDerived>("PolyDiamondDerived")
- .smart_ptr<std::shared_ptr<PolyDiamondDerived>>()
+ .smart_ptr<std::shared_ptr<PolyDiamondDerived>>("shared_ptr<PolyDiamondDerived>")
.constructor<>()
.function("getClassName", &PolyDiamondDerived::getClassName)
;
class_<PolyDiamondSiblingDerived>("PolyDiamondSiblingDerived")
- .smart_ptr<std::shared_ptr<PolyDiamondSiblingDerived>>()
+ .smart_ptr<std::shared_ptr<PolyDiamondSiblingDerived>>("shared_ptr<PolyDiamondSiblingDerived>")
.constructor<>()
.function("getClassName", &PolyDiamondSiblingDerived::getClassName)
;
class_<PolyDiamondMultiplyDerived>("PolyDiamondMultiplyDerived")
- .smart_ptr<std::shared_ptr<PolyDiamondMultiplyDerived>>()
+ .smart_ptr<std::shared_ptr<PolyDiamondMultiplyDerived>>("shared_ptr<PolyDiamondMultiplyDerived>")
.constructor<>()
.function("getClassName", &PolyDiamondMultiplyDerived::getClassName)
;
@@ -1825,8 +1825,8 @@ EMSCRIPTEN_BINDINGS(tests) {
auto HeldBySmartPtr_class = class_<HeldBySmartPtr>("HeldBySmartPtr");
HeldBySmartPtr_class
- .smart_ptr<CustomSmartPtr<HeldBySmartPtr>>()
- .smart_ptr_constructor(&std::make_shared<HeldBySmartPtr, int, std::string>)
+ .smart_ptr<CustomSmartPtr<HeldBySmartPtr>>("CustomSmartPtr<HeldBySmartPtr>")
+ .smart_ptr_constructor("shared_ptr<HeldbySmartPtr>", &std::make_shared<HeldBySmartPtr, int, std::string>)
.class_function("newCustomPtr", HeldBySmartPtr::newCustomPtr)
.function("returnThis", &takesHeldBySmartPtrSharedPtr)
.property("i", &HeldBySmartPtr::i)
@@ -1836,8 +1836,8 @@ EMSCRIPTEN_BINDINGS(tests) {
function("takesHeldBySmartPtrSharedPtr", &takesHeldBySmartPtrSharedPtr);
class_<HeldByCustomSmartPtr>("HeldByCustomSmartPtr")
- .smart_ptr<std::shared_ptr<HeldByCustomSmartPtr>>()
- .smart_ptr_constructor(&HeldByCustomSmartPtr::create)
+ .smart_ptr<std::shared_ptr<HeldByCustomSmartPtr>>("shared_ptr<HeldByCustomSmartPtr>")
+ .smart_ptr_constructor("CustomSmartPtr<HeldByCustomSmartPtr>", &HeldByCustomSmartPtr::create)
.class_function("createSharedPtr", &HeldByCustomSmartPtr::createSharedPtr)
.property("i", &HeldByCustomSmartPtr::i)
.property("s", &HeldByCustomSmartPtr::s)
@@ -2022,7 +2022,7 @@ EMSCRIPTEN_BINDINGS(overloads) {
;
class_<MultipleSmartCtors>("MultipleSmartCtors")
- .smart_ptr<std::shared_ptr<MultipleSmartCtors>>()
+ .smart_ptr<std::shared_ptr<MultipleSmartCtors>>("shared_ptr<MultipleSmartCtors>")
.constructor(&std::make_shared<MultipleSmartCtors, int>)
.constructor(&std::make_shared<MultipleSmartCtors, int, int>)
.function("WhichCtorCalled", &MultipleSmartCtors::WhichCtorCalled)
@@ -2147,6 +2147,8 @@ struct BoundClass {
};
EMSCRIPTEN_BINDINGS(incomplete) {
+ constant("hasUnboundTypeNames", emscripten::has_unbound_type_names);
+
function("getUnboundClass", &passThrough<UnboundClass>);
class_<HasUnboundBase, base<UnboundClass>>("HasUnboundBase")
@@ -2247,7 +2249,7 @@ std::shared_ptr<Base> return_Base_from_DerivedWithOffset(std::shared_ptr<Derived
EMSCRIPTEN_BINDINGS(with_adjustment) {
class_<DerivedWithOffset, base<Base>>("DerivedWithOffset")
- .smart_ptr_constructor(&std::make_shared<DerivedWithOffset>)
+ .smart_ptr_constructor("shared_ptr<DerivedWithOffset>", &std::make_shared<DerivedWithOffset>)
;
function("return_Base_from_DerivedWithOffset", &return_Base_from_DerivedWithOffset);
diff --git a/tests/test_core.py b/tests/test_core.py
index 07a7bf77..ab4897f8 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -2983,7 +2983,7 @@ def process(filename):
output_nicerizer=lambda x, err: x.replace('\n', '*'),
post_build=self.dlfcn_post_build)
- if Settings.ASM_JS and os.path.exists(SPIDERMONKEY_ENGINE[0]):
+ if Settings.ASM_JS and SPIDERMONKEY_ENGINE and os.path.exists(SPIDERMONKEY_ENGINE[0]):
out = run_js('liblib.so', engine=SPIDERMONKEY_ENGINE, full_output=True, stderr=STDOUT)
if 'asm' in out:
self.validate_asmjs(out)
diff --git a/tools/shared.py b/tools/shared.py
index e912a700..82bdd98b 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -746,13 +746,14 @@ else:
# Engine tweaks
try:
- new_spidermonkey = listify(SPIDERMONKEY_ENGINE)
- if 'gcparam' not in str(new_spidermonkey):
- new_spidermonkey += ['-e', "gcparam('maxBytes', 1024*1024*1024);"] # Our very large files need lots of gc heap
- if '-w' not in str(new_spidermonkey):
- new_spidermonkey += ['-w']
- JS_ENGINES = map(lambda x: new_spidermonkey if x == SPIDERMONKEY_ENGINE else x, JS_ENGINES)
- SPIDERMONKEY_ENGINE = new_spidermonkey
+ if SPIDERMONKEY_ENGINE:
+ new_spidermonkey = listify(SPIDERMONKEY_ENGINE)
+ if 'gcparam' not in str(new_spidermonkey):
+ new_spidermonkey += ['-e', "gcparam('maxBytes', 1024*1024*1024);"] # Our very large files need lots of gc heap
+ if '-w' not in str(new_spidermonkey):
+ new_spidermonkey += ['-w']
+ JS_ENGINES = map(lambda x: new_spidermonkey if x == SPIDERMONKEY_ENGINE else x, JS_ENGINES)
+ SPIDERMONKEY_ENGINE = new_spidermonkey
except NameError:
pass