Hi, sorry I am a bit confused (my knowledge of html and javascript is quite
basic), because I dont understand how that can be used in javascript to
ensure that the runtime is ready. For example the following results in the
same error :
<!DOCTYPE html>
<html>
<script type="text/javascript">
var Module = {
onRuntimeInitialized: function() {
Module._test();
dotest();
}
};
</script>
<script type='text/javascript' src="a.out.js"></script>
<head>
<meta charset="UTF-8">
<title>simple page</title>
</head>
<body>
<script type='text/javascript'>
function dotest(){
mytest = Module.cwrap('test', 'number', ['number']);
var result = mytest(0);
return result;
}
document.write(dotest());
document.write('<BR/>');
document.write("\rFinished!");
</script>
</body>
</html>
Thanks
On Wednesday, April 8, 2015 at 9:29:04 PM UTC+1, Alon Zakai wrote:
>
> onRuntimeInitialized should call the test code. Instead of the test code
> running immediately. For example put the test code in a function called
> doTest(), and call that from onRuntimeInitialized.
>
> - Alon
>
>
> On Wed, Apr 8, 2015 at 12:47 PM, <[email protected] <javascript:>> wrote:
>
>> Hi, how should I correctly modify the html? I was just trying to use the
>> method you mentioned in
>> https://groups.google.com/d/msg/emscripten-discuss/xDHk29DJ6zI/l5ishrLBu7UJ
>>
>> Thanks
>>
>> On Wednesday, April 8, 2015 at 8:17:34 PM UTC+1, Alon Zakai wrote:
>>>
>>> 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] <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.