I just put the js in an empty html file, and looked in the web console at the output.
- Alon On Tue, Apr 7, 2015 at 1:32 PM, <[email protected]> wrote: > 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]> 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. > -- 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.
