That html looks invalid. It will run the code in the last script tag immediately, without waiting for onRuntimeInitialized.
- Alon On Tue, Apr 7, 2015 at 11:47 PM, <[email protected]> wrote: > Hi, it also works for me in the console (I hadn't tried that until you > mentioned). However it fails in the following html in both chrome and > firefox (but only with O2/O3 optimisations. With O0, O1 it works fine) : > > <!DOCTYPE html> > <html> > > <head> > <meta charset="UTF-8"> > <title>simple page</title> > </head> > > <body> > > <script type="text/javascript"> > var Module = { onRuntimeInitialized: function() { > Module._test(); > } }; > </script> > > <script type='text/javascript' src="a.out.js"></script> > > <script type='text/javascript'> > mytest = Module.cwrap('test', 'number', ['number']); > var result = mytest(0); > document.write(result); > document.write('<BR/>'); > document.write("\rFinished!"); > </script> > > </body> > > </html> > > On Wednesday, April 8, 2015 at 12:40:02 AM UTC+1, Alon Zakai wrote: >> >> 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. > -- 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.
