I built with -O3 and ran it in html, and I can't see the problem. Perhaps try other browsers and versions, you may have found a browser bug.
- Alon On Mon, Apr 6, 2015 at 1:09 PM, <[email protected]> wrote: > Just to clarify, building with em++ is fine. I only get a problem when it > try to use the resulting a.out.js in html. Thanks > > On Monday, April 6, 2015 at 7:53:28 PM UTC+1, Alon Zakai wrote: >> >> What are the steps to reproduce the problem? I build that source file >> with -O0, 1, 2 and 3, and in all of them I get "42" as the output. >> >> - Alon >> >> >> On Sat, Apr 4, 2015 at 7:12 AM, <[email protected]> wrote: >> >>> OK the following self contained code (*not* calling any boost headers) >>> is fine with O0 or O1, but not with O2 or O3. The function which I am >>> exporting is : >>> >>> extern "C" { >>> double test(void) { >>> boost::shared_ptr<int> y = boost::shared_ptr<int>(new int(42)); >>> return *y; >>> } >>> } >>> >>> The invocation of "dispose()" and "weak_release()" in >>> "sp_counted_base::release" is what is causing the problems : >>> >>> #include <atomic> >>> #include <iostream> >>> #include <vector> >>> using namespace std; >>> >>> namespace boost >>> { >>> >>> namespace core >>> { >>> >>> >>> class typeinfo >>> { >>> private: >>> >>> typeinfo( typeinfo const& ); >>> typeinfo& operator=( typeinfo const& ); >>> >>> char const * name_; >>> >>> public: >>> >>> explicit typeinfo( char const * name ): name_( name ) >>> { >>> } >>> >>> bool operator==( typeinfo const& rhs ) const >>> { >>> return this == &rhs; >>> } >>> >>> bool operator!=( typeinfo const& rhs ) const >>> { >>> return this != &rhs; >>> } >>> >>> bool before( typeinfo const& rhs ) const >>> { >>> return std::less< typeinfo const* >()( this, &rhs ); >>> } >>> >>> char const* name() const >>> { >>> return name_; >>> } >>> }; >>> >>> >>> }//namespace core >>> >>> template<class T> class shared_ptr; >>> template<class T> class enable_shared_from_this; >>> >>> template<class T> inline void checked_delete(T * x) >>> { >>> // intentionally complex - simplification causes regressions >>> typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; >>> (void) sizeof(type_must_be_complete); >>> delete x; >>> } >>> >>> namespace detail >>> { >>> >>> typedef boost::core::typeinfo sp_typeinfo; >>> >>> inline void atomic_increment( std::atomic_int_least32_t * pw ) >>> { >>> pw->fetch_add( 1, std::memory_order_relaxed ); >>> } >>> >>> inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * >>> pw ) >>> { >>> return pw->fetch_sub( 1, std::memory_order_acq_rel ); >>> } >>> >>> inline std::int_least32_t atomic_conditional_increment( >>> std::atomic_int_least32_t * pw ) >>> { >>> // long r = *pw; >>> // if( r != 0 ) ++*pw; >>> // return r; >>> >>> std::int_least32_t r = pw->load( std::memory_order_relaxed ); >>> >>> for( ;; ) >>> { >>> if( r == 0 ) >>> { >>> return r; >>> } >>> >>> if( pw->compare_exchange_weak( r, r + 1, >>> std::memory_order_relaxed, std::memory_order_relaxed ) ) >>> { >>> return r; >>> } >>> } >>> } >>> >>> class sp_counted_base >>> { >>> private: >>> >>> sp_counted_base( sp_counted_base const & ); >>> sp_counted_base & operator= ( sp_counted_base const & ); >>> >>> std::atomic_int_least32_t use_count_; // #shared >>> std::atomic_int_least32_t weak_count_; // #weak + (#shared != 0) >>> >>> public: >>> >>> sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) >>> { >>> } >>> >>> virtual ~sp_counted_base() // nothrow >>> { >>> } >>> >>> // dispose() is called when use_count_ drops to zero, to release >>> // the resources managed by *this. >>> >>> virtual void dispose() = 0; // nothrow >>> >>> // destroy() is called when weak_count_ drops to zero. >>> >>> virtual void destroy() // nothrow >>> { >>> delete this; >>> } >>> >>> virtual void * get_deleter( sp_typeinfo const & ti ) = 0; >>> virtual void * get_untyped_deleter() = 0; >>> >>> void add_ref_copy() >>> { >>> atomic_increment( &use_count_ ); >>> } >>> >>> bool add_ref_lock() // true on success >>> { >>> return atomic_conditional_increment( &use_count_ ) != 0; >>> } >>> >>> void release() // nothrow >>> { >>> if( atomic_decrement( &use_count_ ) == 1 ) >>> { >>> dispose(); >>> weak_release(); >>> } >>> } >>> >>> void weak_add_ref() // nothrow >>> { >>> atomic_increment( &weak_count_ ); >>> } >>> >>> void weak_release() // nothrow >>> { >>> if( atomic_decrement( &weak_count_ ) == 1 ) >>> { >>> destroy(); >>> } >>> } >>> >>> long use_count() const // nothrow >>> { >>> return use_count_.load( std::memory_order_acquire ); >>> } >>> }; >>> >>> >>> template<class X> class sp_counted_impl_p: public sp_counted_base >>> { >>> private: >>> >>> X * px_; >>> >>> sp_counted_impl_p( sp_counted_impl_p const & ); >>> sp_counted_impl_p & operator= ( sp_counted_impl_p const & ); >>> >>> typedef sp_counted_impl_p<X> this_type; >>> >>> public: >>> >>> explicit sp_counted_impl_p( X * px ): px_( px ) >>> { >>> #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) >>> boost::sp_scalar_constructor_hook( px, sizeof(X), this ); >>> #endif >>> } >>> >>> virtual void dispose() // nothrow >>> { >>> #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) >>> boost::sp_scalar_destructor_hook( px_, sizeof(X), this ); >>> #endif >>> boost::checked_delete( px_ ); >>> } >>> >>> virtual void * get_deleter( detail::sp_typeinfo const & ) >>> { >>> return 0; >>> } >>> >>> virtual void * get_untyped_deleter() >>> { >>> return 0; >>> } >>> >>> #if defined(BOOST_SP_USE_STD_ALLOCATOR) >>> >>> void * operator new( std::size_t ) >>> { >>> return std::allocator<this_type>().allocate( 1, >>> static_cast<this_type *>(0) ); >>> } >>> >>> void operator delete( void * p ) >>> { >>> std::allocator<this_type>().deallocate( static_cast<this_type >>> *>(p), 1 ); >>> } >>> >>> #endif >>> >>> #if defined(BOOST_SP_USE_QUICK_ALLOCATOR) >>> >>> void * operator new( std::size_t ) >>> { >>> return quick_allocator<this_type>::alloc(); >>> } >>> >>> void operator delete( void * p ) >>> { >>> quick_allocator<this_type>::dealloc( p ); >>> } >>> >>> #endif >>> }; >>> >>> class shared_count >>> { >>> private: >>> >>> sp_counted_base * pi_; >>> >>> public: >>> >>> void swap(shared_count & r) // nothrow >>> { >>> sp_counted_base * tmp = r.pi_; >>> r.pi_ = pi_; >>> pi_ = tmp; >>> } >>> >>> shared_count(): pi_(0) // nothrow >>> #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) >>> , id_(shared_count_id) >>> #endif >>> { >>> } >>> >>> template<class Y> explicit shared_count( Y * p ): pi_( 0 ) >>> #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) >>> , id_(shared_count_id) >>> #endif >>> { >>> #ifndef BOOST_NO_EXCEPTIONS >>> >>> try >>> { >>> pi_ = new sp_counted_impl_p<Y>( p ); >>> } >>> catch(...) >>> { >>> boost::checked_delete( p ); >>> throw; >>> } >>> >>> #else >>> >>> pi_ = new sp_counted_impl_p<Y>( p ); >>> >>> if( pi_ == 0 ) >>> { >>> boost::checked_delete( p ); >>> boost::throw_exception( std::bad_alloc() ); >>> } >>> >>> #endif >>> } >>> >>> >>> shared_count(shared_count && r): pi_(r.pi_) // nothrow >>> #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) >>> , id_(shared_count_id) >>> #endif >>> { >>> r.pi_ = 0; >>> } >>> >>> ~shared_count() // nothrow >>> { >>> if( pi_ != 0 ) pi_->release(); >>> #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) >>> id_ = 0; >>> #endif >>> } >>> >>> }; >>> >>> template< class T > struct sp_element >>> { >>> typedef T type; >>> }; >>> >>> template< class X, class Y, class T > inline void >>> sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, >>> boost::enable_shared_from_this< T > const * pe ) >>> { >>> if( pe != 0 ) >>> { >>> pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) ); >>> } >>> } >>> >>> struct sp_any_pointer >>> { >>> template<class T> sp_any_pointer( T* ) {} >>> }; >>> >>> inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, >>> sp_any_pointer ) >>> { >>> } >>> >>> template< class T, class Y > inline void sp_pointer_construct( >>> boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn ) >>> { >>> boost::detail::shared_count( p ).swap( pn ); >>> boost::detail::sp_enable_shared_from_this( ppx, p, p ); >>> } >>> >>> template< class T > struct sp_dereference >>> { >>> typedef T & type; >>> }; >>> >>> }//namespace detail >>> >>> template<class T> class shared_ptr >>> { >>> private: >>> >>> // Borland 5.5.1 specific workaround >>> typedef shared_ptr<T> this_type; >>> >>> public: >>> >>> typedef typename boost::detail::sp_element< T >::type element_type; >>> >>> template<class Y> >>> explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete >>> { >>> boost::detail::sp_pointer_construct( this, p, pn ); >>> } >>> >>> element_type * px; // contained pointer >>> boost::detail::shared_count pn; // reference counter >>> >>> typename boost::detail::sp_dereference< T >::type operator* () const >>> { >>> return *px; >>> } >>> >>> }; >>> >>> } // namespace boost >>> >>> extern "C" { >>> double test(void) { >>> boost::shared_ptr<int> y = boost::shared_ptr<int>(new int(42)); >>> return *y; >>> } >>> } >>> >>> int main(void){ >>> double result = test(); >>> cout<<result<<endl; >>> return 0; >>> } >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "emscripten-discuss" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to [email protected]. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> -- > You received this message because you are subscribed to the Google Groups > "emscripten-discuss" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "emscripten-discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
