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] <javascript:>> 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] <javascript:>. >> 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.
