Hi, I am actually getting the same behaviour in chrome and firefox. What does the html code that you are using to access the function look like? Thanks
On Monday, April 6, 2015 at 10:41:05 PM UTC+1, Alon Zakai wrote: > > 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] <javascript:>> 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] <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.
