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.

Reply via email to