diff options
-rw-r--r-- | cmake/Platform/Emscripten.cmake | 7 | ||||
-rw-r--r-- | system/include/emscripten/bind.h | 22 | ||||
-rw-r--r-- | system/include/emscripten/wire.h | 64 | ||||
-rw-r--r-- | system/lib/embind/bind.cpp | 38 | ||||
-rw-r--r-- | tests/cmake/target_html/CMakeLists.txt | 32 | ||||
-rw-r--r-- | tests/core/test_atomic_cxx.cpp | 34 | ||||
-rw-r--r-- | tests/core/test_atomic_cxx.txt | 52 | ||||
-rw-r--r-- | tests/embind/embind.test.js | 6 | ||||
-rw-r--r-- | tests/embind/embind_test.cpp | 54 | ||||
-rw-r--r-- | tests/test_core.py | 2 | ||||
-rw-r--r-- | tools/shared.py | 15 |
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 |