diff --git a/include/hx/GC.h b/include/hx/GC.h
index 5370c142e..a9148c505 100644
--- a/include/hx/GC.h
+++ b/include/hx/GC.h
@@ -363,7 +363,12 @@ class ImmixAllocator
    {
       #ifdef HXCPP_GC_NURSERY
 
+         #ifdef HXCPP_ALIGN_ALLOC
+         // make sure buffer is 8-byte aligned
+         unsigned char *buffer = alloc->spaceFirst + ( (size_t)alloc->spaceFirst & 4 );
+         #else
          unsigned char *buffer = alloc->spaceFirst;
+         #endif
          unsigned char *end = buffer + (inSize + 4);
 
          if ( end > alloc->spaceOversize )
@@ -381,6 +386,10 @@ class ImmixAllocator
                ((unsigned int *)buffer)[-1] = inSize;
          }
 
+         #if defined(HXCPP_GC_CHECK_POINTER) && defined(HXCPP_GC_DEBUG_ALWAYS_MOVE)
+         hx::GCOnNewPointer(buffer);
+         #endif
+
          #ifdef HXCPP_TELEMETRY
          __hxt_gc_new((hx::StackContext *)alloc,buffer, inSize, inName);
          #endif
@@ -388,41 +397,43 @@ class ImmixAllocator
          return buffer;
 
       #else
-         #ifndef HXCPP_ALIGN_ALLOC
-            // Inline the fast-path if we can
-            // We know the object can hold a pointer (vtable) and that the size is int-aligned
-            int start = alloc->spaceStart;
-            int end = start + sizeof(int) + inSize;
-
-            if ( end <= alloc->spaceEnd )
-            {
-               alloc->spaceStart = end;
-
-               unsigned int *buffer = (unsigned int *)(alloc->allocBase + start);
-
-               int startRow = start>>IMMIX_LINE_BITS;
-
-               alloc->allocStartFlags[ startRow ] |= gImmixStartFlag[start&127];
-
-               if (inContainer)
-                  *buffer++ =  (( (end+(IMMIX_LINE_LEN-1))>>IMMIX_LINE_BITS) -startRow) |
-                               (inSize<<IMMIX_ALLOC_SIZE_SHIFT) |
-                               hx::gMarkIDWithContainer;
-               else
-                  *buffer++ =  (( (end+(IMMIX_LINE_LEN-1))>>IMMIX_LINE_BITS) -startRow) |
-                               (inSize<<IMMIX_ALLOC_SIZE_SHIFT) |
-                               hx::gMarkID;
-
-               #if defined(HXCPP_GC_CHECK_POINTER) && defined(HXCPP_GC_DEBUG_ALWAYS_MOVE)
-               hx::GCOnNewPointer(buffer);
-               #endif
-
-               #ifdef HXCPP_TELEMETRY
-               __hxt_gc_new((hx::StackContext *)alloc,buffer, inSize, inName);
-               #endif
-               return buffer;
-            }
-         #endif // HXCPP_ALIGN_ALLOC
+         // Inline the fast-path if we can
+         // We know the object can hold a pointer (vtable) and that the size is int-aligned
+         int start = alloc->spaceStart;
+         #ifdef HXCPP_ALIGN_ALLOC
+            // Ensure odd alignment in 8 bytes
+            start += 4 - (start & 4);
+         #endif
+         int end = start + sizeof(int) + inSize;
+
+         if ( end <= alloc->spaceEnd )
+         {
+            alloc->spaceStart = end;
+
+            unsigned int *buffer = (unsigned int *)(alloc->allocBase + start);
+
+            int startRow = start>>IMMIX_LINE_BITS;
+
+            alloc->allocStartFlags[ startRow ] |= gImmixStartFlag[start&127];
+
+            if (inContainer)
+               *buffer++ =  (( (end+(IMMIX_LINE_LEN-1))>>IMMIX_LINE_BITS) -startRow) |
+                            (inSize<<IMMIX_ALLOC_SIZE_SHIFT) |
+                            hx::gMarkIDWithContainer;
+            else
+               *buffer++ =  (( (end+(IMMIX_LINE_LEN-1))>>IMMIX_LINE_BITS) -startRow) |
+                            (inSize<<IMMIX_ALLOC_SIZE_SHIFT) |
+                            hx::gMarkID;
+
+            #if defined(HXCPP_GC_CHECK_POINTER) && defined(HXCPP_GC_DEBUG_ALWAYS_MOVE)
+            hx::GCOnNewPointer(buffer);
+            #endif
+
+            #ifdef HXCPP_TELEMETRY
+            __hxt_gc_new((hx::StackContext *)alloc,buffer, inSize, inName);
+            #endif
+            return buffer;
+         }
 
          // Fall back to external method
          void *result = alloc->CallAlloc(inSize, inContainer ? IMMIX_ALLOC_IS_CONTAINER : 0);
diff --git a/include/hx/Thread.h b/include/hx/Thread.h
index b2c3bbfb4..069d51e87 100644
--- a/include/hx/Thread.h
+++ b/include/hx/Thread.h
@@ -91,22 +91,28 @@ struct HxMutex
       pthread_mutexattr_t mta;
       pthread_mutexattr_init(&mta);
       pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
-      mValid = pthread_mutex_init(&mMutex,&mta) ==0;
+      mMutex = new pthread_mutex_t();
+      mValid = pthread_mutex_init(mMutex,&mta) ==0;
    }
-   ~HxMutex() { if (mValid) pthread_mutex_destroy(&mMutex); }
-   void Lock() { pthread_mutex_lock(&mMutex); }
-   void Unlock() { pthread_mutex_unlock(&mMutex); }
-   bool TryLock() { return !pthread_mutex_trylock(&mMutex); }
+   ~HxMutex()
+   {
+      if (mValid)
+         pthread_mutex_destroy(mMutex);
+      delete mMutex;
+   }
+   void Lock() { pthread_mutex_lock(mMutex); }
+   void Unlock() { pthread_mutex_unlock(mMutex); }
+   bool TryLock() { return !pthread_mutex_trylock(mMutex); }
    bool IsValid() { return mValid; }
    void Clean()
    {
       if (mValid)
-         pthread_mutex_destroy(&mMutex);
+         pthread_mutex_destroy(mMutex);
       mValid = 0;
    }
 
    bool mValid;
-   pthread_mutex_t mMutex;
+   pthread_mutex_t *mMutex;
 };
 
 #define THREAD_FUNC_TYPE void *
@@ -196,13 +202,14 @@ struct HxSemaphore
    {
       mSet = false;
       mValid = true;
-      pthread_cond_init(&mCondition,0);
+      mCondition = new pthread_cond_t();
+      pthread_cond_init(mCondition,0);
    }
    ~HxSemaphore()
    {
       if (mValid)
       {
-         pthread_cond_destroy(&mCondition);
+         pthread_cond_destroy(mCondition);
       }
    }
    // For autolock
@@ -213,13 +220,13 @@ struct HxSemaphore
       if (!mSet)
       {
          mSet = true;
-         pthread_cond_signal( &mCondition );
+         pthread_cond_signal( mCondition );
       }
    }
    void QSet()
    {
       mSet = true;
-      pthread_cond_signal( &mCondition );
+      pthread_cond_signal( mCondition );
    }
    void Reset()
    {
@@ -231,14 +238,14 @@ struct HxSemaphore
    {
       AutoLock lock(mMutex);
       while( !mSet )
-         pthread_cond_wait( &mCondition, &mMutex.mMutex );
+         pthread_cond_wait( mCondition, mMutex.mMutex );
       mSet = false;
    }
    // when we already hold the mMutex lock ...
    void QWait()
    {
       while( !mSet )
-         pthread_cond_wait( &mCondition, &mMutex.mMutex );
+         pthread_cond_wait( mCondition, mMutex.mMutex );
       mSet = false;
    }
    // Returns true if the wait was success, false on timeout.
@@ -262,7 +269,7 @@ struct HxSemaphore
 
       int result = 0;
       // Wait for set to be true...
-      while( !mSet &&  (result=pthread_cond_timedwait( &mCondition, &mMutex.mMutex, &spec )) != ETIMEDOUT)
+      while( !mSet &&  (result=pthread_cond_timedwait( mCondition, mMutex.mMutex, &spec )) != ETIMEDOUT)
       {
          if (result!=0)
          {
@@ -290,13 +297,14 @@ struct HxSemaphore
       if (mValid)
       {
          mValid = false;
-         pthread_cond_destroy(&mCondition);
+         pthread_cond_destroy(mCondition);
       }
+      delete mCondition;
    }
 
 
    HxMutex         mMutex;
-   pthread_cond_t  mCondition;
+   pthread_cond_t  *mCondition;
    bool            mSet;
    bool            mValid;
 };
diff --git a/include/hxcpp.h b/include/hxcpp.h
index b2568d142..faa1b4db2 100755
--- a/include/hxcpp.h
+++ b/include/hxcpp.h
@@ -70,7 +70,7 @@
 
 // Must allign allocs to 8 bytes to match floating point requirement?
 // Ints must br read on 4-byte boundary
-#if defined(EMSCRIPTEN) || defined(GCW0)
+#if (!defined(HXCPP_ALIGN_FLOAT) && (defined(EMSCRIPTEN) || defined(GCW0)) )
    #define HXCPP_ALIGN_ALLOC
 #endif
 
diff --git a/src/hx/libs/ssl/mbedtls_config.h b/project/thirdparty/config/mbedtls/include/mbedtls_config.h
similarity index 100%
rename from src/hx/libs/ssl/mbedtls_config.h
rename to project/thirdparty/config/mbedtls/include/mbedtls_config.h
diff --git a/src/hx/libs/ssl/threading_alt.h b/project/thirdparty/config/mbedtls/include/threading_alt.h
similarity index 100%
rename from src/hx/libs/ssl/threading_alt.h
rename to project/thirdparty/config/mbedtls/include/threading_alt.h
diff --git a/project/thirdparty/mbedtls-files.xml b/project/thirdparty/mbedtls-files.xml
new file mode 100644
index 000000000..2c092ed5b
--- /dev/null
+++ b/project/thirdparty/mbedtls-files.xml
@@ -0,0 +1,113 @@
+<xml>
+
+<set name="MBEDTLS_DIR" value="${HXCPP}/project/thirdparty/mbedtls-2.28.2" />
+
+<files id="mbedtls">
+	<depend name="${this_dir}/mbedtls-files.xml" dateOnly="true" />
+	<cache value="true" asLibrary="true" />
+
+	<include name="${this_dir}/mbedtls-flags.xml" />
+
+	<compilerflag value="-std=c99" unless="MSVC_VER" />
+
+	<file name="${MBEDTLS_DIR}/library/aes.c" />
+	<file name="${MBEDTLS_DIR}/library/aesni.c" />
+	<file name="${MBEDTLS_DIR}/library/arc4.c" />
+	<file name="${MBEDTLS_DIR}/library/aria.c" />
+	<file name="${MBEDTLS_DIR}/library/asn1parse.c" />
+	<file name="${MBEDTLS_DIR}/library/asn1write.c" />
+	<file name="${MBEDTLS_DIR}/library/base64.c" />
+	<file name="${MBEDTLS_DIR}/library/bignum.c" />
+	<file name="${MBEDTLS_DIR}/library/blowfish.c" />
+	<file name="${MBEDTLS_DIR}/library/camellia.c" />
+	<file name="${MBEDTLS_DIR}/library/ccm.c" />
+	<file name="${MBEDTLS_DIR}/library/chacha20.c" />
+	<file name="${MBEDTLS_DIR}/library/chachapoly.c" />
+	<file name="${MBEDTLS_DIR}/library/cipher.c" />
+	<file name="${MBEDTLS_DIR}/library/cipher_wrap.c" />
+	<file name="${MBEDTLS_DIR}/library/constant_time.c" />
+	<file name="${MBEDTLS_DIR}/library/cmac.c" />
+	<file name="${MBEDTLS_DIR}/library/ctr_drbg.c" />
+	<file name="${MBEDTLS_DIR}/library/des.c" />
+	<file name="${MBEDTLS_DIR}/library/dhm.c" />
+	<file name="${MBEDTLS_DIR}/library/ecdh.c" />
+	<file name="${MBEDTLS_DIR}/library/ecdsa.c" />
+	<file name="${MBEDTLS_DIR}/library/ecjpake.c" />
+	<file name="${MBEDTLS_DIR}/library/ecp.c" />
+	<file name="${MBEDTLS_DIR}/library/ecp_curves.c" />
+	<file name="${MBEDTLS_DIR}/library/entropy.c" />
+	<file name="${MBEDTLS_DIR}/library/entropy_poll.c" />
+	<file name="${MBEDTLS_DIR}/library/error.c" />
+	<file name="${MBEDTLS_DIR}/library/gcm.c" />
+	<file name="${MBEDTLS_DIR}/library/havege.c" />
+	<file name="${MBEDTLS_DIR}/library/hkdf.c" />
+	<file name="${MBEDTLS_DIR}/library/hmac_drbg.c" />
+	<file name="${MBEDTLS_DIR}/library/md.c" />
+	<file name="${MBEDTLS_DIR}/library/md2.c" />
+	<file name="${MBEDTLS_DIR}/library/md4.c" />
+	<file name="${MBEDTLS_DIR}/library/md5.c" />
+	<file name="${MBEDTLS_DIR}/library/memory_buffer_alloc.c" />
+	<file name="${MBEDTLS_DIR}/library/mps_reader.c" />
+	<file name="${MBEDTLS_DIR}/library/mps_trace.c" />
+	<file name="${MBEDTLS_DIR}/library/nist_kw.c" />
+	<file name="${MBEDTLS_DIR}/library/oid.c" />
+	<file name="${MBEDTLS_DIR}/library/padlock.c" />
+	<file name="${MBEDTLS_DIR}/library/pem.c" />
+	<file name="${MBEDTLS_DIR}/library/pk.c" />
+	<file name="${MBEDTLS_DIR}/library/pk_wrap.c" />
+	<file name="${MBEDTLS_DIR}/library/pkcs12.c" />
+	<file name="${MBEDTLS_DIR}/library/pkcs5.c" />
+	<file name="${MBEDTLS_DIR}/library/pkparse.c" />
+	<file name="${MBEDTLS_DIR}/library/pkwrite.c" />
+	<file name="${MBEDTLS_DIR}/library/platform.c" />
+	<file name="${MBEDTLS_DIR}/library/platform_util.c" />
+	<file name="${MBEDTLS_DIR}/library/poly1305.c" />
+	<file name="${MBEDTLS_DIR}/library/psa_crypto.c" />
+	<file name="${MBEDTLS_DIR}/library/psa_crypto_aead.c" />
+	<file name="${MBEDTLS_DIR}/library/psa_crypto_cipher.c" />
+	<file name="${MBEDTLS_DIR}/library/psa_crypto_client.c" />
+	<file name="${MBEDTLS_DIR}/library/psa_crypto_driver_wrappers.c" />
+	<file name="${MBEDTLS_DIR}/library/psa_crypto_ecp.c" />
+	<file name="${MBEDTLS_DIR}/library/psa_crypto_hash.c" />
+	<file name="${MBEDTLS_DIR}/library/psa_crypto_mac.c" />
+	<file name="${MBEDTLS_DIR}/library/psa_crypto_rsa.c" />
+	<file name="${MBEDTLS_DIR}/library/psa_crypto_se.c" />
+	<file name="${MBEDTLS_DIR}/library/psa_crypto_slot_management.c" />
+	<file name="${MBEDTLS_DIR}/library/psa_crypto_storage.c" />
+	<file name="${MBEDTLS_DIR}/library/psa_its_file.c" />
+	<file name="${MBEDTLS_DIR}/library/ripemd160.c" />
+	<file name="${MBEDTLS_DIR}/library/rsa.c" />
+	<file name="${MBEDTLS_DIR}/library/rsa_internal.c" />
+	<file name="${MBEDTLS_DIR}/library/sha1.c" />
+	<file name="${MBEDTLS_DIR}/library/sha256.c" />
+	<file name="${MBEDTLS_DIR}/library/sha512.c" />
+	<file name="${MBEDTLS_DIR}/library/threading.c" />
+	<file name="${MBEDTLS_DIR}/library/timing.c" />
+	<file name="${MBEDTLS_DIR}/library/version.c" />
+	<file name="${MBEDTLS_DIR}/library/version_features.c" />
+	<file name="${MBEDTLS_DIR}/library/xtea.c" />
+
+	<file name="${MBEDTLS_DIR}/library/certs.c" />
+	<file name="${MBEDTLS_DIR}/library/pkcs11.c" />
+	<file name="${MBEDTLS_DIR}/library/x509.c" />
+	<file name="${MBEDTLS_DIR}/library/x509_create.c" />
+	<file name="${MBEDTLS_DIR}/library/x509_crl.c" />
+	<file name="${MBEDTLS_DIR}/library/x509_crt.c" />
+	<file name="${MBEDTLS_DIR}/library/x509_csr.c" />
+	<file name="${MBEDTLS_DIR}/library/x509write_crt.c" />
+	<file name="${MBEDTLS_DIR}/library/x509write_csr.c" />
+
+	<file name="${MBEDTLS_DIR}/library/debug.c" />
+	<file name="${MBEDTLS_DIR}/library/net_sockets.c" />
+	<file name="${MBEDTLS_DIR}/library/ssl_cache.c" />
+	<file name="${MBEDTLS_DIR}/library/ssl_ciphersuites.c" />
+	<file name="${MBEDTLS_DIR}/library/ssl_cli.c" />
+	<file name="${MBEDTLS_DIR}/library/ssl_cookie.c" />
+	<file name="${MBEDTLS_DIR}/library/ssl_msg.c" />
+	<file name="${MBEDTLS_DIR}/library/ssl_srv.c" />
+	<file name="${MBEDTLS_DIR}/library/ssl_ticket.c" />
+	<file name="${MBEDTLS_DIR}/library/ssl_tls.c" />
+	<file name="${MBEDTLS_DIR}/library/ssl_tls13_keys.c" />
+</files>
+
+</xml>
diff --git a/project/thirdparty/mbedtls-flags.xml b/project/thirdparty/mbedtls-flags.xml
new file mode 100644
index 000000000..aa2905c22
--- /dev/null
+++ b/project/thirdparty/mbedtls-flags.xml
@@ -0,0 +1,9 @@
+<xml>
+
+<depend name="${HXCPP}/project/thirdparty/mbedtls-flags.xml" dateOnly="true" />
+
+<compilerflag value="-I${HXCPP}/project/thirdparty/mbedtls-2.28.2/include" />
+<compilerflag value="-I${HXCPP}/project/thirdparty/config/mbedtls/include" />
+<compilerflag value="-DMBEDTLS_USER_CONFIG_FILE=&lt;mbedtls_config.h&gt;" />
+
+</xml>
diff --git a/src/Dynamic.cpp b/src/Dynamic.cpp
index 7a51401b5..9d52c070e 100644
--- a/src/Dynamic.cpp
+++ b/src/Dynamic.cpp
@@ -217,7 +217,7 @@ class PointerData : public hx::Object
    String toString()
    {
       char buf[100];
-      sprintf(buf,"Pointer(%p)", mValue);
+      snprintf(buf,sizeof(buf),"Pointer(%p)", mValue);
       return String(buf);
    }
    String __ToString() const { return String(mValue); }
diff --git a/src/hx/CFFI.cpp b/src/hx/CFFI.cpp
index 81575a67c..592c8e230 100644
--- a/src/hx/CFFI.cpp
+++ b/src/hx/CFFI.cpp
@@ -106,7 +106,7 @@ class Abstract_obj : public Object
          return _hxcpp_toString( Dynamic(this) );
 
       char buffer[40];
-      sprintf(buffer,"0x%p", mHandle);
+      snprintf(buffer,sizeof(buffer),"0x%p", mHandle);
 
       return HX_CSTRING("Abstract(") +
              __hxcpp_get_kind(this) +
diff --git a/src/hx/Debug.cpp b/src/hx/Debug.cpp
index 462cdaae1..9cd52c3f0 100644
--- a/src/hx/Debug.cpp
+++ b/src/hx/Debug.cpp
@@ -77,12 +77,15 @@ static void CriticalErrorHandler(String inErr, bool allowFixup)
       return;
 #endif
 
+#ifdef HXCPP_STACK_TRACE
+   hx::StackContext *ctx = hx::StackContext::getCurrent();
+   ctx->beginCatch(true);
+#endif
+
    if (sCriticalErrorHandler!=null())
       sCriticalErrorHandler(inErr);
 
 #ifdef HXCPP_STACK_TRACE
-   hx::StackContext *ctx = hx::StackContext::getCurrent();
-   ctx->beginCatch(true);
    ctx->dumpExceptionStack();
 #endif
 
diff --git a/src/hx/Thread.cpp b/src/hx/Thread.cpp
index 0dedb89d9..e5af49df3 100644
--- a/src/hx/Thread.cpp
+++ b/src/hx/Thread.cpp
@@ -628,8 +628,8 @@ class hxCondition : public hx::Object {
 	CONDITION_VARIABLE cond;
 #endif
 #else
-	pthread_cond_t cond;
-	pthread_mutex_t mutex;
+	pthread_cond_t *cond;
+	pthread_mutex_t *mutex;
 #endif
   hx::InternalFinalizer *mFinalizer;
   hxCondition() {
@@ -645,11 +645,13 @@ class hxCondition : public hx::Object {
 #else
     pthread_condattr_t cond_attr;
     pthread_condattr_init(&cond_attr);
-    pthread_cond_init(&cond, &cond_attr);
+    cond = new pthread_cond_t();
+    pthread_cond_init(cond, &cond_attr);
     pthread_condattr_destroy(&cond_attr);
     pthread_mutexattr_t mutex_attr;
     pthread_mutexattr_init(&mutex_attr);
-    pthread_mutex_init(&mutex, &mutex_attr);
+    mutex = new pthread_mutex_t();
+    pthread_mutex_init(mutex, &mutex_attr);
     pthread_mutexattr_destroy(&mutex_attr);
 #endif
   }
@@ -667,8 +669,10 @@ class hxCondition : public hx::Object {
       DeleteCriticalSection(&cond->cs);
 #endif
 #else
-      pthread_cond_destroy(&cond->cond);
-      pthread_mutex_destroy(&cond->mutex);
+      pthread_cond_destroy(cond->cond);
+      delete cond->cond;
+      pthread_mutex_destroy(cond->mutex);
+      delete cond->mutex;
 #endif
     }
   }
@@ -679,7 +683,7 @@ class hxCondition : public hx::Object {
 	  EnterCriticalSection(&cs);
 #endif
 #else
-	  pthread_mutex_lock(&mutex);
+	  pthread_mutex_lock(mutex);
 #endif
   }
 
@@ -691,7 +695,7 @@ class hxCondition : public hx::Object {
 	return false;
 #endif
 #else
-    return pthread_mutex_trylock(&mutex);
+    return pthread_mutex_trylock(mutex);
 #endif
   }
 
@@ -701,7 +705,7 @@ class hxCondition : public hx::Object {
 	  LeaveCriticalSection(&cs);
 #endif
 #else
-	  pthread_mutex_unlock(&mutex);
+	  pthread_mutex_unlock(mutex);
 #endif
   }
 
@@ -711,7 +715,7 @@ class hxCondition : public hx::Object {
 	  SleepConditionVariableCS(&cond,&cs,INFINITE);
 #endif
 #else
-	  pthread_cond_wait(&cond, &mutex);
+	  pthread_cond_wait(cond, mutex);
 #endif
   }
 
@@ -735,7 +739,7 @@ class hxCondition : public hx::Object {
     delta -= idelta2 * 1e9;
     t.tv_sec = tv.tv_sec + idelta + idelta2;
     t.tv_nsec = (long)delta;
-    return pthread_cond_timedwait(&cond, &mutex, &t);
+    return pthread_cond_timedwait(cond, mutex, &t);
 #endif
   }
   void Signal() {
@@ -744,7 +748,7 @@ class hxCondition : public hx::Object {
 	  WakeConditionVariable(&cond);
 #endif
 #else
-	  pthread_cond_signal(&cond);
+	  pthread_cond_signal(cond);
 #endif
   }
   void Broadcast() {
@@ -753,7 +757,7 @@ class hxCondition : public hx::Object {
 	  WakeAllConditionVariable(&cond);
 #endif
 #else
-	  pthread_cond_broadcast(&cond);
+	  pthread_cond_broadcast(cond);
 #endif
   }
 };
diff --git a/src/hx/gc/Immix.cpp b/src/hx/gc/Immix.cpp
index 4894f79e3..05d0ac842 100644
--- a/src/hx/gc/Immix.cpp
+++ b/src/hx/gc/Immix.cpp
@@ -7,6 +7,14 @@
 #include "GcRegCapture.h"
 #include <hx/Unordered.h>
 
+#ifdef EMSCRIPTEN
+   #include <emscripten/stack.h>
+   #ifdef HXCPP_SINGLE_THREADED_APP
+      // Use provided tools to measure stack extent
+      #define HXCPP_EXPLICIT_STACK_EXTENT
+   #endif
+#endif
+
 #include <string>
 #include <stdlib.h>
 
@@ -28,7 +36,6 @@ int gSlowPath = 0;
 using hx::gByteMarkID;
 using hx::gRememberedByteMarkID;
 
-// #define HXCPP_SINGLE_THREADED_APP
 
 namespace hx
 {
@@ -108,10 +115,6 @@ static size_t sgMaximumFreeSpace  = 1024*1024*1024;
 static size_t sgMaximumFreeSpace  = 1024*1024*1024;
 #endif
 
-#ifdef EMSCRIPTEN
-// #define HXCPP_STACK_UP
-#endif
-
 
 // #define HXCPP_GC_DEBUG_LEVEL 1
 
@@ -137,7 +140,7 @@ static size_t sgMaximumFreeSpace  = 1024*1024*1024;
 //#define HXCPP_GC_SUMMARY
 //#define PROFILE_COLLECT
 //#define PROFILE_THREAD_USAGE
-//#define HX_GC_VERIFY
+//#define HXCPP_GC_VERIFY
 //#define HX_GC_VERIFY_ALLOC_START
 //#define SHOW_MEM_EVENTS
 //#define SHOW_MEM_EVENTS_VERBOSE
@@ -155,7 +158,7 @@ static size_t sgMaximumFreeSpace  = 1024*1024*1024;
 //  every collect so you can see where it goes wrong (usually requires HX_GC_FIXED_BLOCKS)
 //#define HX_WATCH
 
-#if defined(HX_GC_VERIFY) && defined(HXCPP_GC_GENERATIONAL)
+#if defined(HXCPP_GC_VERIFY) && defined(HXCPP_GC_GENERATIONAL)
 #define HX_GC_VERIFY_GENERATIONAL
 #endif
 
@@ -189,7 +192,7 @@ static bool sGcVerifyGenerational = false;
 #endif
 
 
-#if HX_HAS_ATOMIC && (HXCPP_GC_DEBUG_LEVEL==0) && !defined(HX_GC_VERIFY) && !defined(EMSCRIPTEN)
+#if HX_HAS_ATOMIC && (HXCPP_GC_DEBUG_LEVEL==0) && !defined(HXCPP_GC_VERIFY) && !defined(EMSCRIPTEN)
   #if defined(HX_MACOS) || defined(HX_WINDOWS) || defined(HX_LINUX)
   enum { MAX_GC_THREADS = 4 };
   #else
@@ -580,7 +583,7 @@ static ThreadPoolLock sThreadPoolLock;
 typedef pthread_cond_t ThreadPoolSignal;
 inline void WaitThreadLocked(ThreadPoolSignal &ioSignal)
 {
-   pthread_cond_wait(&ioSignal, &sThreadPoolLock.mMutex);
+   pthread_cond_wait(&ioSignal, sThreadPoolLock.mMutex);
 }
 #else
 typedef HxSemaphore ThreadPoolSignal;
@@ -725,6 +728,13 @@ static int gBlockInfoEmptySlots = 0;
 #define ZEROED_THREAD 1
 #define ZEROED_AUTO   2
 
+// Align padding based on block offset
+#ifdef HXCPP_ALIGN_ALLOC
+    #define ALIGN_PADDING(x) (4-(x&4))
+#else
+    #define ALIGN_PADDING(x) 0
+#endif
+
 struct BlockDataInfo
 {
    int             mId;
@@ -1199,6 +1209,13 @@ struct BlockDataInfo
          int last = scan + mRanges[h].length;
          if (inOffset<last)
          {
+            #ifdef HXCPP_ALIGN_ALLOC
+            // Make sure header scan is odd-int aligned so the following object will be even-int
+            // aligned
+            if (!(scan & 0x4))
+               scan += 4;
+            #endif
+
             // Found hole that the object was possibly allocated in
             while(scan<=inOffset)
             {
@@ -1234,6 +1251,12 @@ struct BlockDataInfo
                   return allocString;
                }
                scan = end;
+               #ifdef HXCPP_ALIGN_ALLOC
+               // Make sure scan is odd-int aligned so the following object will be even-int
+               // aligned
+               if (!(scan & 0x4))
+                  scan += 4;
+               #endif
             }
             break;
          }
@@ -1350,7 +1373,7 @@ struct BlockDataInfo
    }
    #endif
 
-   #ifdef HX_GC_VERIFY
+   #ifdef HXCPP_GC_VERIFY
    void verify(const char *inWhere)
    {
       for(int i=IMMIX_HEADER_LINES;i<IMMIX_LINES;i++)
@@ -1468,6 +1491,14 @@ void GCCheckPointer(void *inPtr)
 
 void GCOnNewPointer(void *inPtr)
 {
+   #ifdef HXCPP_ALIGN_ALLOC
+   if ( (size_t)inPtr & 0x7 )
+   {
+      GCLOG("Misaligned pointer %p\n", inPtr);
+      NullReference("Object", false);
+   }
+   #endif
+
    #ifdef HXCPP_GC_DEBUG_ALWAYS_MOVE
    hx::sgPointerMoved.erase(inPtr);
    _hx_atomic_add(&sgAllocsSinceLastSpam, 1);
@@ -3518,7 +3549,7 @@ class GlobalAllocator
       for(int i=0;i<BLOCK_OFSIZE_COUNT;i++)
          mNextFreeBlockOfSize[i] = newSize;
 
-      #ifdef HX_GC_VERIFY
+      #ifdef HXCPP_GC_VERIFY
       VerifyBlockOrder();
       #endif
 
@@ -3743,7 +3774,7 @@ class GlobalAllocator
                         int size = ((header & IMMIX_ALLOC_SIZE_MASK) >> IMMIX_ALLOC_SIZE_SHIFT);
                         int allocSize = size + sizeof(int);
 
-                        while(allocSize>destLen)
+                        while(allocSize + ALIGN_PADDING(destPos)>destLen)
                         {
                            hole++;
                            if (hole<holes)
@@ -3775,6 +3806,10 @@ class GlobalAllocator
                            }
                         }
 
+                        #ifdef HXCPP_ALIGN_ALLOC
+                        destPos += ALIGN_PADDING(destPos);
+                        #endif
+
                         int startRow = destPos>>IMMIX_LINE_BITS;
 
                         destStarts[ startRow ] |= hx::gImmixStartFlag[destPos&127];
@@ -3894,6 +3929,8 @@ class GlobalAllocator
       return 0;
    }
 
+ 
+
    int MoveSurvivors(hx::QuickVec<hx::Object *> *inRemembered)
    {
       int sourceScan = 0;
@@ -3948,7 +3985,7 @@ class GlobalAllocator
                            int allocSize = size + sizeof(int);
 
                            // Find dest reqion ...
-                           while(destHole==0 || destLen<allocSize)
+                           while(destHole==0 || destLen < ALIGN_PADDING(destPos) + allocSize)
                            {
                               if (destHole==0)
                               {
@@ -3961,7 +3998,7 @@ class GlobalAllocator
                                  destHole = -1;
                                  destLen = 0;
                               }
-                              if (destLen<allocSize)
+                              if (destLen + ALIGN_PADDING(0)<allocSize)
                               {
                                  destHole++;
                                  if (destHole>=destInfo->mHoles)
@@ -3978,6 +4015,11 @@ class GlobalAllocator
 
                            // TODO - not copy + paste
 
+                        printf("Move!\n");
+                           #ifdef HXCPP_ALIGN_ALLOC
+                           destPos += ALIGN_PADDING(destPos);
+                           #endif
+
                            int startRow = destPos>>IMMIX_LINE_BITS;
 
                            destStarts[ startRow ] |= hx::gImmixStartFlag[destPos&127];
@@ -4057,7 +4099,7 @@ class GlobalAllocator
              gAllocGroups[mAllBlocks[i]->mGroupId].isEmpty=false;
       }
 
-      #ifdef HX_GC_VERIFY
+      #ifdef HXCPP_GC_VERIFY
       typedef std::pair< void *, void * > ReleasedRange;
       std::vector<ReleasedRange> releasedRange;
       std::vector<int> releasedGids;
@@ -4073,7 +4115,7 @@ class GlobalAllocator
             #ifdef SHOW_MEM_EVENTS_VERBOSE
             GCLOG("Release group %d: %p -> %p\n", i, g.alloc, g.alloc+groupBytes);
             #endif
-            #ifdef HX_GC_VERIFY
+            #ifdef HXCPP_GC_VERIFY
             releasedRange.push_back( ReleasedRange(g.alloc, g.alloc+groupBytes) );
             releasedGids.push_back(i);
             #endif
@@ -4102,7 +4144,7 @@ class GlobalAllocator
          }
          else
          {
-            #ifdef HX_GC_VERIFY
+            #ifdef HXCPP_GC_VERIFY
             for(int g=0;g<releasedGids.size();g++)
                if (mAllBlocks[i]->mGroupId == releasedGids[g])
                {
@@ -4114,7 +4156,7 @@ class GlobalAllocator
          }
       }
 
-      #ifdef HX_GC_VERIFY
+      #ifdef HXCPP_GC_VERIFY
       for(int i=0;i<mAllBlocks.size();i++)
       {
          BlockDataInfo *info = mAllBlocks[i];
@@ -4453,7 +4495,7 @@ class GlobalAllocator
       {
          waitForThreadWake(inId);
 
-         #ifdef HX_GC_VERIFY
+         #ifdef HXCPP_GC_VERIFY
          if (! (sRunningThreads & (1<<inId)) )
             printf("Bad running threads!\n");
          #endif
@@ -4629,11 +4671,11 @@ class GlobalAllocator
 
       char strBuf[100];
       if (bytes<k)
-         sprintf(strBuf,"%d", (int)bytes);
+         snprintf(strBuf,sizeof(strBuf),"%d", (int)bytes);
       else if (bytes<meg)
-         sprintf(strBuf,"%.2fk", (double)bytes/k);
+         snprintf(strBuf,sizeof(strBuf),"%.2fk", (double)bytes/k);
       else
-         sprintf(strBuf,"%.2fmb", (double)bytes/meg);
+         snprintf(strBuf,sizeof(strBuf),"%.2fmb", (double)bytes/meg);
       return strBuf;
    }
    #endif
@@ -4766,7 +4808,7 @@ class GlobalAllocator
 
       hx::RunFinalizers();
 
-      #ifdef HX_GC_VERIFY
+      #ifdef HXCPP_GC_VERIFY
       for(int i=0;i<mAllBlocks.size();i++)
          mAllBlocks[i]->verify("After mark");
       #endif
@@ -4790,7 +4832,7 @@ class GlobalAllocator
    }
    #endif
 
-   #ifdef HX_GC_VERIFY
+   #ifdef HXCPP_GC_VERIFY
    void VerifyBlockOrder()
    {
       for(int i=1;i<mAllBlocks.size();i++)
@@ -5202,7 +5244,7 @@ class GlobalAllocator
 
             std::stable_sort(&mAllBlocks[0], &mAllBlocks[0] + mAllBlocks.size(), SortByBlockPtr );
 
-            #ifdef HX_GC_VERIFY
+            #ifdef HXCPP_GC_VERIFY
             VerifyBlockOrder();
             #endif
          }
@@ -5328,7 +5370,7 @@ class GlobalAllocator
       #endif
 
 
-      #ifdef HX_GC_VERIFY
+      #ifdef HXCPP_GC_VERIFY
       VerifyBlockOrder();
       #endif
 
@@ -5639,7 +5681,13 @@ void MarkConservative(int *inBottom, int *inTop,hx::MarkContext *__inCtx)
       void *vptr = *(void **)ptr;
 
       MemType mem;
-      if (vptr && !((size_t)vptr & 0x03) && vptr!=prev && vptr!=lastPin)
+      #ifdef HXCPP_ALIGN_ALLOC
+      const size_t validObjectMask = 0x07;
+      #else
+      const size_t validObjectMask = 0x03;
+      #endif
+
+      if (vptr && !((size_t)vptr & validObjectMask) && vptr!=prev && vptr!=lastPin)
       {
 
          #ifdef PROFILE_COLLECT
@@ -5762,8 +5810,10 @@ class LocalAllocator : public hx::StackContext
 
    bool           mMoreHoles;
 
+   #ifndef HXCPP_EXPLICIT_STACK_EXTENT
    int *mTopOfStack;
    int *mBottomOfStack;
+   #endif
 
    hx::RegisterCaptureBuffer mRegisterBuf;
    int                   mRegisterBufSize;
@@ -5801,7 +5851,9 @@ class LocalAllocator : public hx::StackContext
 
    void AttachThread(int *inTopOfStack)
    {
+      #ifndef HXCPP_EXPLICIT_STACK_EXTENT
       mTopOfStack = mBottomOfStack = inTopOfStack;
+      #endif
 
       mRegisterBufSize = 0;
       mStackLocks = 0;
@@ -5859,7 +5911,9 @@ class LocalAllocator : public hx::StackContext
       }
       #endif
 
+      #ifndef HXCPP_EXPLICIT_STACK_EXTENT
       mTopOfStack = mBottomOfStack = 0;
+      #endif
 
       sGlobalAlloc->RemoveLocalLocked(this);
 
@@ -5891,7 +5945,7 @@ class LocalAllocator : public hx::StackContext
    // Other places may call this to ensure the the current thread is registered
    //  indefinitely (until forcefully revoked)
    //
-   // Normally liraries/mains will then let this dangle.
+   // Normally libraries/mains will then let this dangle.
    //
    // However after the main, on android it calls SetTopOfStack(0,true), to unregister the thread,
    // because it is likely to be the ui thread, and the remaining call will be from
@@ -5916,13 +5970,28 @@ class LocalAllocator : public hx::StackContext
    //  SetTopOfStack(top,true) -> add stack lock
    //  SetTopOfStack(0,_) -> pop stack lock. If all gone, clear global stack lock
    //
+
+   #ifdef HXCPP_EXPLICIT_STACK_EXTENT // {
+
+   void SetTopOfStack(int *inTop,bool inPush) { }
+   void PushTopOfStack(void *inTop) { }
+   void PopTopOfStack() { }
+   void SetBottomOfStack(int *inBottom) { }
+   void PauseForCollect() { }
+   void EnterGCFreeZone() { }
+   bool TryGCFreeZone() { return true; }
+   bool TryExitGCFreeZone() { return false; }
+   void ExitGCFreeZoneLocked() { }
+
+
+   #else // } !HXCPP_EXPLICIT_STACK_EXTENT {
    void SetTopOfStack(int *inTop,bool inPush)
    {
       if (inTop)
       {
          if (!mTopOfStack)
             mTopOfStack = inTop;
-         // EMSCRIPTEN the stack grows upwards
+         // EMSCRIPTEN the stack grows upwards - not wasm.
          // It could be that the main routine was called from deep with in the stack,
          //  then some callback was called from a higher location on the stack
          #ifdef HXCPP_STACK_UP
@@ -5987,39 +6056,6 @@ class LocalAllocator : public hx::StackContext
       #endif
    }
 
-   virtual void SetupStackAndCollect(bool inMajor, bool inForceCompact, bool inLocked=false,bool inFreeIsFragged=false)
-   {
-      #ifndef HXCPP_SINGLE_THREADED_APP
-        #if HXCPP_DEBUG
-        if (mGCFreeZone)
-           CriticalGCError("Collecting from a GC-free thread");
-        #endif
-      #endif
-
-      volatile int dummy = 1;
-      mBottomOfStack = (int *)&dummy;
-
-      CAPTURE_REGS;
-
-      if (!mTopOfStack)
-         mTopOfStack = mBottomOfStack;
-      // EMSCRIPTEN the stack grows upwards
-      #ifdef HXCPP_STACK_UP
-      if (mBottomOfStack < mTopOfStack)
-         mTopOfStack = mBottomOfStack;
-      #else
-      if (mBottomOfStack > mTopOfStack)
-         mTopOfStack = mBottomOfStack;
-      #endif
-
-      #ifdef VerifyStackRead
-      VerifyStackRead(mBottomOfStack, mTopOfStack)
-      #endif
-
-
-      sGlobalAlloc->Collect(inMajor, inForceCompact, inLocked, inFreeIsFragged);
-   }
-
 
    void PauseForCollect()
    {
@@ -6145,27 +6181,68 @@ class LocalAllocator : public hx::StackContext
       #endif
    }
 
-   void ExpandAlloc(int &ioSize)
+   #endif // }  HXCPP_EXPLICIT_STACK_EXTENT
+
+
+   void SetupStackAndCollect(bool inMajor, bool inForceCompact, bool inLocked=false,bool inFreeIsFragged=false)
    {
-      #ifdef HXCPP_GC_NURSERY
-      int spaceStart = spaceFirst - allocBase - 4;
-      int spaceEnd = spaceOversize - allocBase - 4;
+      #ifndef HXCPP_SINGLE_THREADED_APP
+        #if HXCPP_DEBUG
+        if (mGCFreeZone)
+           CriticalGCError("Collecting from a GC-free thread");
+        #endif
       #endif
 
+      #ifndef HXCPP_EXPLICIT_STACK_EXTENT
+      volatile int dummy = 1;
+      mBottomOfStack = (int *)&dummy;
+
+      CAPTURE_REGS;
 
-      int size = ioSize + sizeof(int);
+      if (!mTopOfStack)
+         mTopOfStack = mBottomOfStack;
+
+      // EMSCRIPTEN the stack grows upwards
+      #ifdef HXCPP_STACK_UP
+      if (mBottomOfStack < mTopOfStack)
+         mTopOfStack = mBottomOfStack;
+      #else
+      if (mBottomOfStack > mTopOfStack)
+         mTopOfStack = mBottomOfStack;
+      #endif
+
+      #ifdef VerifyStackRead
+      VerifyStackRead(mBottomOfStack, mTopOfStack)
+      #endif
+
+      #endif
+
+
+      sGlobalAlloc->Collect(inMajor, inForceCompact, inLocked, inFreeIsFragged);
+   }
+
+
+
+   void ExpandAlloc(int &ioSize)
+   {
       #ifdef HXCPP_ALIGN_ALLOC
-      // If we start in even-int offset, we need to skip 8 bytes to get alloc on even-int
-      if (size+spaceStart>spaceEnd || !(spaceStart & 7))
-         size += 4;
+      // Do nothing here - aligning to the end of the row will bump the
+      // next allocation, so it's not clear if its a good idea.
+      #else
+         #ifdef HXCPP_GC_NURSERY
+         int spaceStart = spaceFirst - allocBase - 4;
+         int spaceEnd = spaceOversize - allocBase - 4;
+         #endif
+
+         int size = ioSize + sizeof(int);
+         int end = spaceStart + size;
+         if (end <= spaceEnd)
+         {
+            int linePad = IMMIX_LINE_LEN - (end & (IMMIX_LINE_LEN-1));
+            if (linePad>0 && linePad<=64)
+               ioSize += linePad;
+         }
       #endif
-      int end = spaceStart + size;
-      if (end <= spaceEnd)
-      {
-         int linePad = IMMIX_LINE_LEN - (end & (IMMIX_LINE_LEN-1));
-         if (linePad>0 && linePad<=64)
-            ioSize += linePad;
-      }
    }
 
 
@@ -6183,20 +6260,13 @@ class LocalAllocator : public hx::StackContext
       if (inSize==0)
          return hx::emptyAlloc;
 
-      #if defined(HXCPP_VISIT_ALLOCS) && defined(HXCPP_M64)
+      #if defined(HXCPP_VISIT_ALLOCS) && (defined(HXCPP_M64)||defined(HXCPP_ARM64))
       // Make sure we can fit a relocation pointer
       int allocSize = sizeof(int) + std::max(8,inSize);
       #else
       int allocSize = sizeof(int) + inSize;
       #endif
 
-      #ifdef HXCPP_ALIGN_ALLOC
-      // If we start in even-int offset, we need to skip 8 bytes to get alloc on even-int
-      int skip4 = allocSize+spaceStart>spaceEnd || !(spaceStart & 7) ? 4 : 0;
-      #else
-      enum { skip4 = 0 };
-      #endif
-
       #if HXCPP_GC_DEBUG_LEVEL>0
       if (inSize & 3) DebuggerTrap();
       #endif
@@ -6205,6 +6275,10 @@ class LocalAllocator : public hx::StackContext
       {
          #ifdef HXCPP_GC_NURSERY
             unsigned char *buffer = spaceFirst;
+            #ifdef HXCPP_ALIGN_ALLOC
+            if ((size_t)buffer & 0x4 )
+               buffer += 4;
+            #endif
             unsigned char *end = buffer + allocSize;
 
             if ( end <= spaceOversize )
@@ -6225,13 +6299,14 @@ class LocalAllocator : public hx::StackContext
             if (s>spaceFirst && mFraggedRows)
                *mFraggedRows += (s - spaceFirst)>>IMMIX_LINE_BITS;
          #else
-            int end = spaceStart + allocSize + skip4;
+            #ifdef HXCPP_ALIGN_ALLOC
+            if (!((size_t)spaceStart & 0x4 ))
+               spaceStart += 4;
+            #endif
+
+            int end = spaceStart + allocSize;
             if (end <= spaceEnd)
             {
-               #ifdef HXCPP_ALIGN_ALLOC
-               spaceStart += skip4;
-               #endif
-
                unsigned int *buffer = (unsigned int *)(allocBase + spaceStart);
 
                int startRow = spaceStart>>IMMIX_LINE_BITS;
@@ -6331,11 +6406,13 @@ class LocalAllocator : public hx::StackContext
 
    void Mark(hx::MarkContext *__inCtx)
    {
+      #ifndef HXCPP_SINGLE_THREADED_APP
       if (!mTopOfStack)
       {
          Reset();
          return;
       }
+      #endif
 
       #ifdef SHOW_MEM_EVENTS
       //int here = 0;
@@ -6345,19 +6422,33 @@ class LocalAllocator : public hx::StackContext
       #ifdef HXCPP_DEBUG
          MarkPushClass("Stack",__inCtx);
          MarkSetMember("Stack",__inCtx);
+
+         #ifdef HXCPP_EXPLICIT_STACK_EXTENT
+           hx::MarkConservative( (int *)emscripten_stack_get_current(),(int *)emscripten_stack_get_base(), __inCtx);
+         #else
          if (mTopOfStack && mBottomOfStack)
             hx::MarkConservative(mBottomOfStack, mTopOfStack , __inCtx);
+         #endif
+
          #ifdef HXCPP_SCRIPTABLE
             MarkSetMember("ScriptStack",__inCtx);
             hx::MarkConservative((int *)(stack), (int *)(pointer),__inCtx);
          #endif
          MarkSetMember("Registers",__inCtx);
          hx::MarkConservative(CAPTURE_REG_START, CAPTURE_REG_END, __inCtx);
+
+
          MarkPopClass(__inCtx);
       #else
-         if (mTopOfStack && mBottomOfStack)
-            hx::MarkConservative(mBottomOfStack, mTopOfStack , __inCtx);
-         hx::MarkConservative(CAPTURE_REG_START, CAPTURE_REG_END, __inCtx);
+
+         #ifdef HXCPP_EXPLICIT_STACK_EXTENT
+           hx::MarkConservative( (int *)emscripten_stack_get_current(), (int *) emscripten_stack_get_base(), __inCtx);
+         #else
+            if (mTopOfStack && mBottomOfStack)
+               hx::MarkConservative(mBottomOfStack, mTopOfStack , __inCtx);
+            hx::MarkConservative(CAPTURE_REG_START, CAPTURE_REG_END, __inCtx);
+         #endif
+
          #ifdef HXCPP_SCRIPTABLE
             hx::MarkConservative((int *)(stack), (int *)(pointer),__inCtx);
          #endif
@@ -6390,6 +6481,7 @@ inline LocalAllocator *GetLocalAlloc(bool inAllowEmpty=false)
    #endif
 }
 
+#ifndef HXCPP_SINGLE_THREADED_APP
 void WaitForSafe(LocalAllocator *inAlloc)
 {
    inAlloc->WaitForSafe();
@@ -6399,6 +6491,7 @@ void ReleaseFromSafe(LocalAllocator *inAlloc)
 {
    inAlloc->ReleaseFromSafe();
 }
+#endif
 
 void MarkLocalAlloc(LocalAllocator *inAlloc,hx::MarkContext *__inCtx)
 {
diff --git a/src/hx/libs/mysql/my_api.cpp b/src/hx/libs/mysql/my_api.cpp
index e6310956b..316469add 100644
--- a/src/hx/libs/mysql/my_api.cpp
+++ b/src/hx/libs/mysql/my_api.cpp
@@ -25,12 +25,12 @@ static void error( MYSQL *m, const char *err, const char *param ) {
 			p2[max - 2] = '.';
 			p2[max - 1] = '.';
 			p2[max] = 0;
-			sprintf(m->last_error,err,param);
+			snprintf(m->last_error,sizeof(m->last_error),err,param);
 			free(p2);
 			return;
 		}
 	}
-	sprintf(m->last_error,err,param);
+	snprintf(m->last_error,sizeof(m->last_error),err,param);
 	m->errcode = -1;
 }
 
@@ -408,7 +408,7 @@ const char *mysql_character_set_name( MYSQL *m ) {
 	const char *name = myp_charset_name(m->infos.server_charset);
 	if( name == NULL ) {
 		static char tmp[512];
-		sprintf(tmp,"#%d",m->infos.server_charset);
+		snprintf(tmp,sizeof(tmp),"#%d",m->infos.server_charset);
 		return tmp;
 	}
 	return name;
diff --git a/src/hx/libs/ssl/Build.xml b/src/hx/libs/ssl/Build.xml
index ae7977d10..2240f564a 100644
--- a/src/hx/libs/ssl/Build.xml
+++ b/src/hx/libs/ssl/Build.xml
@@ -2,124 +2,14 @@
 
 <pragma once="true" />
 
-<set name="MBEDTLS_DIR" value="${HXCPP}/project/thirdparty/mbedtls-2.28.2" />
-
-<files id="mbedtls">
-	<depend name="${this_dir}/Build.xml" dateOnly="true" />
-	<cache value="true" asLibrary="true" />
-
-	<compilerflag value="-I${MBEDTLS_DIR}/include" />
-	<compilerflag value="-I${this_dir}" />
-	<compilerflag value="-std=c99" unless="MSVC_VER" />
-	<compilerflag value="-DMBEDTLS_USER_CONFIG_FILE=&lt;mbedtls_config.h&gt;" />
-
-	<file name="${MBEDTLS_DIR}/library/aes.c" />
-	<file name="${MBEDTLS_DIR}/library/aesni.c" />
-	<file name="${MBEDTLS_DIR}/library/arc4.c" />
-	<file name="${MBEDTLS_DIR}/library/aria.c" />
-	<file name="${MBEDTLS_DIR}/library/asn1parse.c" />
-	<file name="${MBEDTLS_DIR}/library/asn1write.c" />
-	<file name="${MBEDTLS_DIR}/library/base64.c" />
-	<file name="${MBEDTLS_DIR}/library/bignum.c" />
-	<file name="${MBEDTLS_DIR}/library/blowfish.c" />
-	<file name="${MBEDTLS_DIR}/library/camellia.c" />
-	<file name="${MBEDTLS_DIR}/library/ccm.c" />
-	<file name="${MBEDTLS_DIR}/library/chacha20.c" />
-	<file name="${MBEDTLS_DIR}/library/chachapoly.c" />
-	<file name="${MBEDTLS_DIR}/library/cipher.c" />
-	<file name="${MBEDTLS_DIR}/library/cipher_wrap.c" />
-	<file name="${MBEDTLS_DIR}/library/constant_time.c" />
-	<file name="${MBEDTLS_DIR}/library/cmac.c" />
-	<file name="${MBEDTLS_DIR}/library/ctr_drbg.c" />
-	<file name="${MBEDTLS_DIR}/library/des.c" />
-	<file name="${MBEDTLS_DIR}/library/dhm.c" />
-	<file name="${MBEDTLS_DIR}/library/ecdh.c" />
-	<file name="${MBEDTLS_DIR}/library/ecdsa.c" />
-	<file name="${MBEDTLS_DIR}/library/ecjpake.c" />
-	<file name="${MBEDTLS_DIR}/library/ecp.c" />
-	<file name="${MBEDTLS_DIR}/library/ecp_curves.c" />
-	<file name="${MBEDTLS_DIR}/library/entropy.c" />
-	<file name="${MBEDTLS_DIR}/library/entropy_poll.c" />
-	<file name="${MBEDTLS_DIR}/library/error.c" />
-	<file name="${MBEDTLS_DIR}/library/gcm.c" />
-	<file name="${MBEDTLS_DIR}/library/havege.c" />
-	<file name="${MBEDTLS_DIR}/library/hkdf.c" />
-	<file name="${MBEDTLS_DIR}/library/hmac_drbg.c" />
-	<file name="${MBEDTLS_DIR}/library/md.c" />
-	<file name="${MBEDTLS_DIR}/library/md2.c" />
-	<file name="${MBEDTLS_DIR}/library/md4.c" />
-	<file name="${MBEDTLS_DIR}/library/md5.c" />
-	<file name="${MBEDTLS_DIR}/library/memory_buffer_alloc.c" />
-	<file name="${MBEDTLS_DIR}/library/mps_reader.c" />
-	<file name="${MBEDTLS_DIR}/library/mps_trace.c" />
-	<file name="${MBEDTLS_DIR}/library/nist_kw.c" />
-	<file name="${MBEDTLS_DIR}/library/oid.c" />
-	<file name="${MBEDTLS_DIR}/library/padlock.c" />
-	<file name="${MBEDTLS_DIR}/library/pem.c" />
-	<file name="${MBEDTLS_DIR}/library/pk.c" />
-	<file name="${MBEDTLS_DIR}/library/pk_wrap.c" />
-	<file name="${MBEDTLS_DIR}/library/pkcs12.c" />
-	<file name="${MBEDTLS_DIR}/library/pkcs5.c" />
-	<file name="${MBEDTLS_DIR}/library/pkparse.c" />
-	<file name="${MBEDTLS_DIR}/library/pkwrite.c" />
-	<file name="${MBEDTLS_DIR}/library/platform.c" />
-	<file name="${MBEDTLS_DIR}/library/platform_util.c" />
-	<file name="${MBEDTLS_DIR}/library/poly1305.c" />
-	<file name="${MBEDTLS_DIR}/library/psa_crypto.c" />
-	<file name="${MBEDTLS_DIR}/library/psa_crypto_aead.c" />
-	<file name="${MBEDTLS_DIR}/library/psa_crypto_cipher.c" />
-	<file name="${MBEDTLS_DIR}/library/psa_crypto_client.c" />
-	<file name="${MBEDTLS_DIR}/library/psa_crypto_driver_wrappers.c" />
-	<file name="${MBEDTLS_DIR}/library/psa_crypto_ecp.c" />
-	<file name="${MBEDTLS_DIR}/library/psa_crypto_hash.c" />
-	<file name="${MBEDTLS_DIR}/library/psa_crypto_mac.c" />
-	<file name="${MBEDTLS_DIR}/library/psa_crypto_rsa.c" />
-	<file name="${MBEDTLS_DIR}/library/psa_crypto_se.c" />
-	<file name="${MBEDTLS_DIR}/library/psa_crypto_slot_management.c" />
-	<file name="${MBEDTLS_DIR}/library/psa_crypto_storage.c" />
-	<file name="${MBEDTLS_DIR}/library/psa_its_file.c" />
-	<file name="${MBEDTLS_DIR}/library/ripemd160.c" />
-	<file name="${MBEDTLS_DIR}/library/rsa.c" />
-	<file name="${MBEDTLS_DIR}/library/rsa_internal.c" />
-	<file name="${MBEDTLS_DIR}/library/sha1.c" />
-	<file name="${MBEDTLS_DIR}/library/sha256.c" />
-	<file name="${MBEDTLS_DIR}/library/sha512.c" />
-	<file name="${MBEDTLS_DIR}/library/threading.c" />
-	<file name="${MBEDTLS_DIR}/library/timing.c" />
-	<file name="${MBEDTLS_DIR}/library/version.c" />
-	<file name="${MBEDTLS_DIR}/library/version_features.c" />
-	<file name="${MBEDTLS_DIR}/library/xtea.c" />
-
-	<file name="${MBEDTLS_DIR}/library/certs.c" />
-	<file name="${MBEDTLS_DIR}/library/pkcs11.c" />
-	<file name="${MBEDTLS_DIR}/library/x509.c" />
-	<file name="${MBEDTLS_DIR}/library/x509_create.c" />
-	<file name="${MBEDTLS_DIR}/library/x509_crl.c" />
-	<file name="${MBEDTLS_DIR}/library/x509_crt.c" />
-	<file name="${MBEDTLS_DIR}/library/x509_csr.c" />
-	<file name="${MBEDTLS_DIR}/library/x509write_crt.c" />
-	<file name="${MBEDTLS_DIR}/library/x509write_csr.c" />
-
-	<file name="${MBEDTLS_DIR}/library/debug.c" />
-	<file name="${MBEDTLS_DIR}/library/net_sockets.c" />
-	<file name="${MBEDTLS_DIR}/library/ssl_cache.c" />
-	<file name="${MBEDTLS_DIR}/library/ssl_ciphersuites.c" />
-	<file name="${MBEDTLS_DIR}/library/ssl_cli.c" />
-	<file name="${MBEDTLS_DIR}/library/ssl_cookie.c" />
-	<file name="${MBEDTLS_DIR}/library/ssl_msg.c" />
-	<file name="${MBEDTLS_DIR}/library/ssl_srv.c" />
-	<file name="${MBEDTLS_DIR}/library/ssl_ticket.c" />
-	<file name="${MBEDTLS_DIR}/library/ssl_tls.c" />
-	<file name="${MBEDTLS_DIR}/library/ssl_tls13_keys.c" />
-</files>
+<include name="${HXCPP}/project/thirdparty/mbedtls-files.xml" />
 
 <files id="hxcpp_ssl" >
 	<depend files="hxcpp-depends"/>
 	<depend name="${this_dir}/Build.xml" dateOnly="true" />
 	<cache value="true" asLibrary="true" />
-	<compilerflag value="-I${MBEDTLS_DIR}/include"/>
-	<compilerflag value="-I${this_dir}"/>
-	<compilerflag value="-DMBEDTLS_USER_CONFIG_FILE=&lt;mbedtls_config.h&gt;"/>
+
+	<include name="${HXCPP}/project/thirdparty/mbedtls-flags.xml" />
 
 	<file name="${this_dir}/SSL.cpp"/>
 </files>
diff --git a/src/hx/libs/zlib/Build.xml b/src/hx/libs/zlib/Build.xml
index de938de3e..de1c69cc5 100644
--- a/src/hx/libs/zlib/Build.xml
+++ b/src/hx/libs/zlib/Build.xml
@@ -13,6 +13,10 @@
   <compilerflag value="-DSTDC" unless="windows" />
   <compilerflag value="-DHAVE_UNISTD_H" unless="windows" />
 
+  <compilerflag value="-Wno-unknown-warning" unless="MSVC_VER" />
+  <compilerflag value="-Wno-unknown-warning-option" unless="MSVC_VER" />
+  <compilerflag value="-Wno-deprecated-non-prototype" unless="MSVC_VER" />
+
   <file name="ZLib.cpp"/>
 
   <!-- HXCPP_LINK_NO_ZLIB may be set too late, so use filterout as well. -->
diff --git a/test/cppia/Client.hx b/test/cppia/Client.hx
index f73cb3078..85a8b274a 100644
--- a/test/cppia/Client.hx
+++ b/test/cppia/Client.hx
@@ -159,6 +159,14 @@ class Client
          return;
       }
 
+
+      final extending = new ClientExtendedExtendedRoot();
+
+      extending.addValue();
+
+      Common.clientRoot = extending;
+
+
       Common.clientImplementation = new ClientOne();
       Common.status = "ok";
 
diff --git a/test/cppia/ClientExtendedExtendedRoot.hx b/test/cppia/ClientExtendedExtendedRoot.hx
new file mode 100644
index 000000000..9465dc60e
--- /dev/null
+++ b/test/cppia/ClientExtendedExtendedRoot.hx
@@ -0,0 +1,7 @@
+class ClientExtendedExtendedRoot extends HostExtendedRoot {
+    override function addValue() {
+        super.addValue();
+
+        values.push(2);
+    }
+}
\ No newline at end of file
diff --git a/test/cppia/Common.hx b/test/cppia/Common.hx
index 7f4c1920f..99f80f815 100644
--- a/test/cppia/Common.hx
+++ b/test/cppia/Common.hx
@@ -3,6 +3,7 @@ class Common
    public static var status:String = "tests not run";
    public static var hostImplementation:pack.HostInterface;
    public static var clientImplementation:pack.HostInterface;
+   public static var clientRoot:HostRoot;
 
    public static var callbackSet:Int = 0;
    public static var callback: Void->Void;
diff --git a/test/cppia/CppiaHost.hx b/test/cppia/CppiaHost.hx
index 3ef7e3108..611a09c2e 100644
--- a/test/cppia/CppiaHost.hx
+++ b/test/cppia/CppiaHost.hx
@@ -1,6 +1,7 @@
 import cpp.cppia.Host;
 
 import HostBase;
+import HostExtendedRoot;
 
 class HostOne implements pack.HostInterface
 {
@@ -84,6 +85,20 @@ class CppiaHost
             Sys.println("Bad cppia closure");
             Sys.exit(-1);
          }
+
+         #if (haxe >= version("4.3.6"))
+         if (Common.clientRoot == null) {
+            Sys.println("null client root class");
+            Sys.exit(-1);
+         }
+         switch Common.clientRoot.values {
+            case [ 0, 1, 2 ]:
+               //
+            case _:
+               Sys.println("Unexpected items in array");
+               Sys.exit(-1);   
+         }
+         #end
       }
    }
 }
diff --git a/test/cppia/HostExtendedRoot.hx b/test/cppia/HostExtendedRoot.hx
new file mode 100644
index 000000000..ad45ae1b3
--- /dev/null
+++ b/test/cppia/HostExtendedRoot.hx
@@ -0,0 +1,7 @@
+class HostExtendedRoot extends HostRoot {
+    override function addValue() {
+        super.addValue();
+
+        values.push(1);
+    }
+}
\ No newline at end of file
diff --git a/test/cppia/HostRoot.hx b/test/cppia/HostRoot.hx
new file mode 100644
index 000000000..1d4181918
--- /dev/null
+++ b/test/cppia/HostRoot.hx
@@ -0,0 +1,11 @@
+class HostRoot {
+    public final values:Array<Int>;
+
+    public function new() {
+        values = [];
+    }
+
+    public function addValue() {
+        values.push(0);
+    }
+}
\ No newline at end of file
diff --git a/test/haxe/compile.hxml b/test/haxe/compile.hxml
index 2a23d789e..eedd52a3d 100644
--- a/test/haxe/compile.hxml
+++ b/test/haxe/compile.hxml
@@ -2,4 +2,4 @@
 -r TestMain.hx
 -D HXCPP_GC_GENERATIONAL
 -L utest
---cpp bin
\ No newline at end of file
+--cpp bin
diff --git a/toolchain/android-toolchain-clang.xml b/toolchain/android-toolchain-clang.xml
index 870931257..6ebbd5001 100644
--- a/toolchain/android-toolchain-clang.xml
+++ b/toolchain/android-toolchain-clang.xml
@@ -3,7 +3,7 @@
 <!-- Set architecture -->
 <section if="HXCPP_X86">
   <set name="ARCH" value="-x86" />
-  <set name="PLATFORM_NUMBER" value="19" unless="PLATFORM_NUMBER" />
+  <set name="PLATFORM_NUMBER" value="21" unless="PLATFORM_NUMBER" />
   <set name="ABITRIPLE" value="i686-linux-android" />
 </section>
 
@@ -15,7 +15,7 @@
 
 <section if="HXCPP_ARMV7">
   <set name="ARCH" value="-v7" />
-  <set name="PLATFORM_NUMBER" value="19" unless="PLATFORM_NUMBER" />
+  <set name="PLATFORM_NUMBER" value="21" unless="PLATFORM_NUMBER" />
   <set name="ABITRIPLE" value="armv7a-linux-androideabi" />
   <set name="EXEPREFIX" value="arm-linux-androideabi" />
 </section>
@@ -92,6 +92,9 @@
   <flag value ="-shared" />
   <flag value="--target=${ABITRIPLE}${PLATFORM_NUMBER}" />
 
+  <!-- Build time error, not run time -->
+  <flag value="-Wl,--no-undefined" unless="HXCPP_ALLOW_UNDEFINED" />
+
   <flag value ="-static-libstdc++" />
   <!-- This shows the android link line, which may be so long that it breaks the tool
      https://github.com/HaxeFoundation/hxcpp/pull/1091
diff --git a/toolchain/appletvos-toolchain.xml b/toolchain/appletvos-toolchain.xml
index 7bc504e1b..9b70a3eeb 100644
--- a/toolchain/appletvos-toolchain.xml
+++ b/toolchain/appletvos-toolchain.xml
@@ -24,8 +24,10 @@
   <!-- <cppflag value="-fvisibility-inlines-hidden"/> -->
   <pchflag value="-x" />
   <pchflag value="c++-header" />
-  <flag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
-  <flag value="-stdlib=libc++" if="HXCPP_CPP11" />
+  <cppflag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
+  <cppflag value="-stdlib=libc++" if="HXCPP_CPP11" />
+  <mmflag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
+  <mmflag value="-stdlib=libc++" if="HXCPP_CPP11" />
   <flag value="-g" if="HXCPP_DEBUG_LINK"/>
   <flag value="-O2" unless="debug"/>
   <flag value="-arch"/>
@@ -69,8 +71,10 @@
 <linker id="dll" exe="g++" >
   <exe name="xcrun --sdk appletvos${TVOS_VER} g++" if="HXCPP_GCC" />
   <exe name="xcrun --sdk appletvos${TVOS_VER} clang++" />
-  <flag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
-  <flag value="-stdlib=libc++" if="HXCPP_CPP11" />
+  <cppflag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
+  <cppflag value="-stdlib=libc++" if="HXCPP_CPP11" />
+  <mmflag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
+  <mmflag value="-stdlib=libc++" if="HXCPP_CPP11" />
   <flag value="-dynamiclib"/>
   <flag value="-arch"/>
   <flag value="arm64" if="HXCPP_ARM64" />
diff --git a/toolchain/appletvsim-toolchain.xml b/toolchain/appletvsim-toolchain.xml
index a571f07f4..1e80b5abd 100644
--- a/toolchain/appletvsim-toolchain.xml
+++ b/toolchain/appletvsim-toolchain.xml
@@ -22,8 +22,10 @@
   <!-- <cppflag value="-fvisibility-inlines-hidden"/> -->
   <pchflag value="-x" />
   <pchflag value="c++-header" />
-  <flag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
-  <flag value="-stdlib=libc++" if="HXCPP_CPP11" />
+  <cppflag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
+  <cppflag value="-stdlib=libc++" if="HXCPP_CPP11" />
+  <mmflag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
+  <mmflag value="-stdlib=libc++" if="HXCPP_CPP11" />
   <flag value="-g" if="HXCPP_DEBUG_LINK"/>
   <flag value="-O2" unless="debug"/>
   <flag value="-fmessage-length=0"/>
@@ -76,8 +78,10 @@
 <linker id="dll" exe="g++" >
   <exe name="xcrun --sdk appletvsimulator${TVOS_VER} g++" if="HXCPP_GCC" />
   <exe name="xcrun --sdk appletvsimulator${TVOS_VER} clang++" />
-  <flag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
-  <flag value="-stdlib=libc++" if="HXCPP_CPP11" />
+  <cppflag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
+  <cppflag value="-stdlib=libc++" if="HXCPP_CPP11" />
+  <mmflag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
+  <mmflag value="-stdlib=libc++" if="HXCPP_CPP11" />
   <flag value="-dynamiclib"/>
   <flag value="-arch"/>
   <flag value="i386" unless="HXCPP_M64"/>
diff --git a/toolchain/common-defines.xml b/toolchain/common-defines.xml
index 517d9b401..3f8c111a9 100644
--- a/toolchain/common-defines.xml
+++ b/toolchain/common-defines.xml
@@ -24,6 +24,7 @@
  <flag value="-DHXCPP_GC_CHECK_POINTER" if="HXCPP_GC_CHECK_POINTER" tag="haxe" />
  <flag value="-DHXCPP_GC_DEBUG_ALWAYS_MOVE" if="HXCPP_GC_DEBUG_ALWAYS_MOVE" tag="haxe" />
  <flag value="-DHXCPP_GC_GENERATIONAL" if="HXCPP_GC_GENERATIONAL" tag="haxe" />
+ <flag value="-DHXCPP_ALIGN_ALLOC" if="HXCPP_ALIGN_ALLOC" tag="haxe" />
  <flag value="-DHXCPP_GC_NURSERY" if="HXCPP_GC_NURSERY" tag="haxe" />
  <flag value="-DHXCPP_DLL_IMPORT" if="dll_import" tag="haxe" />
  <flag value="-I${dll_import_include}" if="dll_import_include" tag="haxe" />
@@ -36,6 +37,7 @@
  <flag value='-DHXCPP_API_LEVEL=0' unless="hxcpp_api_level"  tag="haxe"/>
  <flag value='-DHXCPP_OBJC' if="objc"  tag="haxe"/>
  <flag value='-DHXCPP_GC_DEBUG_LEVEL=${HXCPP_GC_DEBUG_LEVEL}' if="HXCPP_GC_DEBUG_LEVEL" tag="gc" />
+ <flag value='-DHXCPP_GC_VERIFY' if="HXCPP_GC_VERIFY" tag="gc" />
  <flag value='-DHXCPP_WINXP_COMPAT' if="HXCPP_WINXP_COMPAT" tag="haxe"/>
  <mmflag value='-Wno-invalid-offsetof' />
  <mmflag value='-Wno-format-security' />
diff --git a/toolchain/emscripten-toolchain.xml b/toolchain/emscripten-toolchain.xml
index cfe102144..ab5316a57 100644
--- a/toolchain/emscripten-toolchain.xml
+++ b/toolchain/emscripten-toolchain.xml
@@ -1,17 +1,60 @@
 <xml>
 
+<!--
+  The Emscipten hxcpp compiler can be invoked from haxe with the 'emscripten' define.
+    haxe -main Main -cpp cpp -D emscripten
+
+  Setup:
+    Emscripten can be installed as per website, then EMSDK, EMSDK_PYTHON and optionally EMSDK_NODE should be set.
+
+  Hxcpp will now generate wasm, not asmjs.
+    Wasm output consists of a ".js" boot file and a ".wasm" file.  The .js file can be run from node directly or
+     via the hxcpp tool, eg: haxelib run hxcpp cpp/Test.js
+
+    If -D HXCPP_LINK_EMSCRIPTEN_EXT=".html" is passed or specified, then an additional html output,
+    eg, Test.html, will be generated.
+
+      Specifying HXCPP_LINK_EMRUN adds code ro redirect output secially for the emrun server.
+
+      The resulting can be used for running the code in a browser from a local server.
+        eg: $EMSDK/upstream/emscripten/emrun(.bat) cpp/Test.html
+
+  Exceptions:
+    You can specify HXCPP_LINK_NO_EXCEPTIONS to reduce overhead by removing exceptions,
+    for example if compiling non-haxe code.  Generally, haxe code needs exceptions.
+
+    -fwasm-exceptions is a newer addition and will be used by default.  If you need
+      greater compatibility, you can specify HXCPP_NO_WASM_EXEPTIONS
+
+  Garbage Collection:
+    Currently, the 'spill-pointers' options is needed for GC.  If you do not need gc,
+    for example compiling non-haxe code, you can disable by specifying HXCPP_NO_GC_LINK
+
+    emscripten target will default to single-threaded, which allows for some GC optimizations
+
+
+-->
+
 <setup name="emscripten" />
 <set name="HXCPP_LINK_EMSCRIPTEN_EXT" value=".js" unless="HXCPP_LINK_EMSCRIPTEN_EXT" />
 
-<path name="${EMSCRIPTEN_SDK}" if="EMSCRIPTEN_SDK" />
-<path name="${dir:EMSCRIPTEN_PYTHON}" if="EMSCRIPTEN_PYTHON" />
+<set name="EMSCRIPTEN_ROOT" value="${EMSDK}/upstream/emscripten" if="EMSDK" unless="EMSCRIPTEN_ROOT" />
+
+<set name="HXCPP_SINGLE_THREADED_APP" value="1" unless="HXCPP_MULTI_THREADED_APP" />
+
+<path name="${EMSDK}" if="EMSDK" />
+<path name="${EMSCRIPTEN_ROOT}" if="EMSCRIPTEN_ROOT" />
+<path name="${dir:EMSDK_PYTHON}" if="EMSDK_PYTHON" />
 <set name="HXCPP_RANLIB" value="emranlib" />
 <set name="HXCPP_AR" value="emar" />
+<set name="HXCPP_M32" value="1"/>
+<unset name="HXCPP_M64" />
 
 <section if="windows_host">
-   <set name="HXCPP_RANLIB" value='python "${EMSCRIPTEN_SDK}/emranlib.py"' />
-   <set name="HXCPP_AR" value='python "${EMSCRIPTEN_SDK}/emar.py"' />
-   <set name="CXX" value='python "${EMSCRIPTEN_SDK}/emcc.py"' />
+   <error value="Please provide EMSDK" unless="EMSCRIPTEN_ROOT" />
+   <set name="HXCPP_RANLIB" value='python "${EMSCRIPTEN_ROOT}/emranlib.py"' />
+   <set name="HXCPP_AR" value='python "${EMSCRIPTEN_ROOT}/emar.py"' />
+   <set name="CXX" value='python "${EMSCRIPTEN_ROOT}/emcc.py"' />
 </section>
 
 <set name="nostrip" value="1" if="emscripten"/>
@@ -28,10 +71,11 @@
         But you may be able to adjust the node stack size ti fix this.
    <set name="HXCPP_OPTIM_LEVEL" value="-O2" />
    -->
-   <set name="HXCPP_OPTIM_LEVEL" value="-O1" />
+   <set name="HXCPP_OPTIM_LEVEL" value="-O2" />
    <set name="HXCPP_OPTIM_LEVEL" value="-g" if="debug" />
 </section>
 
+
 <compiler id="emscripten" exe="emcc">
   <exe name="${CXX}" if="CXX" />
   <flag value="-c"/>
@@ -40,6 +84,10 @@
   <pchflag value="-x" />
   <pchflag value="c++-header" />
   <cppflag value="--std=c++11" />
+  <section unless="HXCPP_LINK_NO_EXCEPTIONS" >
+     <flag name="-s" value="DISABLE_EXCEPTION_CATCHING=0" if="HXCPP_NO_WASM_EXEPTIONS" />
+     <flag value="-fwasm-exceptions" unless="HXCPP_NO_WASM_EXEPTIONS" />
+  </section>
   <flag value="${HXCPP_OPTIM_LEVEL}" />
   <flag value="-fpic" if="HXCPP_EMSCRIPTEN_FPIC" />
   <flag value="-fPIC" if="HXCPP_EMSCRIPTEN_FPIC" />
@@ -99,6 +147,14 @@
     <flag value="${HXCPP_LINK_MEM_FILE}"/>
   </section>
 
+  <flag name="-s" value="WASM=1" />
+  <flag value="--Wno-limited-postlink-optimizations" unless="HXCPP_NO_GC_LINK" />
+  <flag name="-s" value="BINARYEN_EXTRA_PASSES='--spill-pointers'" unless="HXCPP_NO_GC_LINK" />
+  <section unless="HXCPP_LINK_NO_EXCEPTIONS" >
+     <flag name="-s" value="DISABLE_EXCEPTION_CATCHING=0" if="HXCPP_NO_WASM_EXEPTIONS" />
+     <flag value="-fwasm-exceptions" unless="HXCPP_NO_WASM_EXEPTIONS" />
+  </section>
+
   <!-- <flag value="-DBUILD_AS_SHARED_LIBRARY" /> -->
   <!-- <lib name="-ldl"/> -->
   <!-- <ext value=".js"/> -->
@@ -113,18 +169,13 @@
   <fromfile value="" if="GCC_OLD" />
   <flag value="${HXCPP_LINK_OPTIM_LEVEL}" />
 
-  <section unless="HXCPP_LINK_NO_EXCEPTIONS" >
-     <flag value="-s" />
-     <flag value="DISABLE_EXCEPTION_CATCHING=0" />
-  </section>
-
   <section if="HXCPP_LINK_MEMORY_GROWTH" >
      <flag value="-s" />
      <flag value="ALLOW_MEMORY_GROWTH=1" />
   </section>
 
 
-  <section if="HXCPP_LINK_SAFE_HEAP" >
+  <section if="HXCPP_LINK_SAFE_HEAP">
      <flag value="-s" />
      <flag value="SAFE_HEAP=1" />
   </section>
@@ -134,34 +185,36 @@
      <flag value="TOTAL_MEMORY=${HXCPP_LINK_TOTAL_MEMORY}" />
   </section>
 
+
+  <!-- Only for asmjs
   <section if="HXCPP_LINK_MEM_FILE" >
     <flag value="--memory-init-file"/>
     <flag value="${HXCPP_LINK_MEM_FILE}"/>
   </section>
+  -->
 
   <section if="HXCPP_LINK_EMRUN" >
      <flag value="--emrun" />
-     <flag value="-s" />
-     <flag value="DEMANGLE_SUPPORT=1" />
   </section>
 
   <section if="HXCPP_DEBUG_LINK" >
-     <flag value="-s" />
-     <flag value="DEMANGLE_SUPPORT=1" />
      <flag value="-debug" />
   </section>
 
-  <section if="WASM" >
-     <flag value="-s"/>
-     <flag value="WASM=1" />
+  <flag name="-s" value="WASM=1" />
+  <flag value="--Wno-limited-postlink-optimizations" unless="HXCPP_NO_GC_LINK" />
+  <flag name="-s" value="BINARYEN_EXTRA_PASSES='--spill-pointers'" unless="HXCPP_NO_GC_LINK" />
+  <section unless="HXCPP_LINK_NO_EXCEPTIONS" >
+     <flag name="-s" value="DISABLE_EXCEPTION_CATCHING=0" if="HXCPP_NO_WASM_EXEPTIONS" />
+     <flag value="-fwasm-exceptions" unless="HXCPP_NO_WASM_EXEPTIONS" />
   </section>
 
   <section if="BINARYEN_METHOD" >
-     <flag name="-s" />
+     <flag value="-s" />
      <flag value="BINARYEN_METHOD='${BINARYEN_METHOD}'" />
   </section>
 
-  <flag value="--bind" if="HXCPP_JS_PRIME" />
+  <flag value="--bind" />
 
   <!-- <lib name="-ldl"/> -->
   <ext value="${HXCPP_LINK_EMSCRIPTEN_EXT}"/>
diff --git a/toolchain/finish-setup.xml b/toolchain/finish-setup.xml
index 0b6aefc9e..eef2be1ec 100644
--- a/toolchain/finish-setup.xml
+++ b/toolchain/finish-setup.xml
@@ -10,6 +10,7 @@
 <set name="NOCONSOLE" value="${NEEDS_NC}" if="no_console"/>
 <set name="RPI" value="-rpi" if="rpi"/>
 <set name="APIFP" value="-hfp" if="hardfp"/>
+<set name="CPPIA_NO_JIT" value="1" if="emscripten"/>
 
 <set name="STD_MODULE_LINK" value="dll"/>
 
diff --git a/toolchain/haxe-target.xml b/toolchain/haxe-target.xml
index fd2134137..a795596ab 100644
--- a/toolchain/haxe-target.xml
+++ b/toolchain/haxe-target.xml
@@ -1,7 +1,7 @@
 <xml>
 
 <!-- make sure hxcpp.n is up to date -->
-<pleaseUpdateHxcppTool version="3" />
+<pleaseUpdateHxcppTool version="6" />
 
 <pragma once="true" />
 
@@ -12,7 +12,7 @@
 <!-- You can override the exes an "exe" section on your own .hxcpp_config -->
 <!-- You can use replace="1" to change the compiler, or omit to add flags -->
 
-<!-- Library files & targets -------------------------------------->
+<!-- Library files & targets -->
 
 <files id="cffi-depends">
   <depend name="${HXCPP}/include/hx/CFFI.h"/>
diff --git a/toolchain/iphoneos-toolchain.xml b/toolchain/iphoneos-toolchain.xml
index c3fd3307e..305aa6a49 100644
--- a/toolchain/iphoneos-toolchain.xml
+++ b/toolchain/iphoneos-toolchain.xml
@@ -95,8 +95,10 @@
   <exe name="xcrun --sdk iphoneos${IPHONE_VER} g++" if="HXCPP_GCC" />
   <exe name="xcrun --sdk iphoneos${IPHONE_VER} clang++" />
   <flag value="-Wl,-cache_path_lto,/tmp" if="HXCPP_OPTIMIZE_LINK_INCREMENTAL" unless="debug"/>
-  <flag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
-  <flag value="-stdlib=libc++" if="HXCPP_CPP11 || HXCPP_CPP17" />
+  <cppflag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
+  <cppflag value="-stdlib=libc++" if="HXCPP_CPP11 || HXCPP_CPP17" />
+  <mmflag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
+  <mmflag value="-stdlib=libc++" if="HXCPP_CPP11 || HXCPP_CPP17" />
   <flag value="-dynamiclib"/>
   <flag value="-arch"/>
   <flag value="armv6" if="HXCPP_ARMV6" />
diff --git a/toolchain/iphonesim-toolchain.xml b/toolchain/iphonesim-toolchain.xml
index c509b4edd..b98a703ad 100644
--- a/toolchain/iphonesim-toolchain.xml
+++ b/toolchain/iphonesim-toolchain.xml
@@ -89,8 +89,10 @@
 <linker id="dll" exe="g++" >
   <exe name="xcrun --sdk iphonesimulator${IPHONE_VER} g++" if="HXCPP_GCC" />
   <exe name="xcrun --sdk iphonesimulator${IPHONE_VER} clang++" />
-  <flag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
-  <flag value="-stdlib=libc++" if="HXCPP_CPP11 || HXCPP_CPP17" />
+  <cppflag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
+  <cppflag value="-stdlib=libc++" if="HXCPP_CPP11 || HXCPP_CPP17" />
+  <mmflag value="-stdlib=libstdc++" if="FORCE_LIBGCC" />
+  <mmflag value="-stdlib=libc++" if="HXCPP_CPP11 || HXCPP_CPP17" />
   <flag value="-dynamiclib"/>
   <flag value="-arch"/>
   <flag value="i386" unless="HXCPP_M64"/>
diff --git a/toolchain/mac-toolchain.xml b/toolchain/mac-toolchain.xml
index c8e0f760d..f7928cdb0 100644
--- a/toolchain/mac-toolchain.xml
+++ b/toolchain/mac-toolchain.xml
@@ -31,8 +31,11 @@
   <cppflag value="-Wc++14-extensions" if="HXCPP_CPP14"/>
   <cppflag value="-std=c++17" if="HXCPP_CPP17"/>
   <cppflag value="-Wc++17-extensions" if="HXCPP_CPP17"/>
-  <flag value="-stdlib=libc++" unless="STDLIBCPP" />
-  <flag value="-stdlib=libstdc++" if="STDLIBCPP" />
+  <cppflag value="-stdlib=libc++" unless="STDLIBCPP" />
+  <cppflag value="-stdlib=libstdc++" if="STDLIBCPP" />
+  <mmflag value="-stdlib=libc++" unless="STDLIBCPP" />
+  <mmflag value="-stdlib=libstdc++" if="STDLIBCPP" />
+  
   <cppflag value="-frtti"/>
   <pchflag value="-x" />
   <pchflag value="c++-header" />
@@ -74,8 +77,10 @@
   <fromfile value="" if="GCC_OLD" />
   <flag value="-Wl,-bundle,-bundle_loader,${dll_import_link}" if="dll_import_link" />
   <flag value="-Wl,-cache_path_lto,/tmp" if="HXCPP_LTO_THIN" unless="debug"/>
-  <flag value="-stdlib=libc++" unless="STDLIBCPP" />
-  <flag value="-stdlib=libstdc++" if="STDLIBCPP" />
+  <cppflag value="-stdlib=libc++" unless="STDLIBCPP" />
+  <cppflag value="-stdlib=libstdc++" if="STDLIBCPP" />
+  <mmflag value="-stdlib=libc++" unless="STDLIBCPP" />
+  <mmflag value="-stdlib=libstdc++" if="STDLIBCPP" />
   <flag value="-fpic"/>
   <flag value="-fPIC"/>
   <flag value="-dynamiclib"/>
@@ -99,7 +104,10 @@
   <flag value="-Wl,-rpath,${HXCPP_RPATH}" if="HXCPP_RPATH" />
   <flag value="-Wl,-cache_path_lto,/tmp" if="HXCPP_OPTIMIZE_LINK_INCREMENTAL" unless="debug"/>
   <fromfile value="" if="GCC_OLD" />
-  <flag value="-stdlib=libstdc++" if="STDLIBCPP" />
+  <cppflag value="-stdlib=libc++" unless="STDLIBCPP" />
+  <cppflag value="-stdlib=libstdc++" if="STDLIBCPP" />
+  <mmflag value="-stdlib=libc++" unless="STDLIBCPP" />
+  <mmflag value="-stdlib=libstdc++" if="STDLIBCPP" />
   <flag value="-framework"/>
   <flag value="Cocoa"/>
   <flag value="-isysroot" unless="LEGACY_MACOSX_SDK"/>
diff --git a/toolchain/msvc-toolchain.xml b/toolchain/msvc-toolchain.xml
index 26c7a826c..83749ba16 100644
--- a/toolchain/msvc-toolchain.xml
+++ b/toolchain/msvc-toolchain.xml
@@ -108,6 +108,8 @@
   <flag value="-wd4996"/>
   <outflag value="-Fo"/>
   <ext value=".obj"/>
+  <asmExe value="ml64.exe" if="HXCPP_M64" />
+  <asmExe value="ml.exe" unless="HXCPP_M64" />
   <objdir value="${MSVC_OBJ_DIR}" />
 
   <rcexe name="rc.exe" />
diff --git a/tools/hxcpp/BuildTool.hx b/tools/hxcpp/BuildTool.hx
index a98a00361..d6b42f513 100644
--- a/tools/hxcpp/BuildTool.hx
+++ b/tools/hxcpp/BuildTool.hx
@@ -894,12 +894,17 @@ class BuildTool
          if (valid(el,""))
             switch(el.name)
             {
-               case "flag" : c.addFlag(substitute(el.att.value), el.has.tag?substitute(el.att.tag):"");
+               case "flag" :
+                     var tag =  el.has.tag?substitute(el.att.tag):"";
+                     if (el.has.name)
+                        c.addFlag(substitute(el.att.name), tag);
+                     c.addFlag(substitute(el.att.value), tag);
                case "cflag" : c.mCFlags.push(substitute(el.att.value));
                case "cppflag" : c.mCPPFlags.push(substitute(el.att.value));
                case "objcflag" : c.mOBJCFlags.push(substitute(el.att.value));
                case "rcflag" : c.mRcFlags.push( substitute((el.att.value)) );
                case "mmflag" : c.mMMFlags.push(substitute(el.att.value));
+               case "asmflag" : c.mAsmFlags.push(substitute(el.att.value));
                case "pchflag" : c.mPCHFlags.push(substitute(el.att.value));
                case "objdir" : c.mObjDir = substitute((el.att.value));
                case "outflag" : c.mOutFlag = substitute((el.att.value));
@@ -907,6 +912,7 @@ class BuildTool
                case "rcexe" : c.mRcExe = substitute((el.att.name));
                case "rcext" : c.mRcExt = substitute((el.att.value));
                case "ext" : c.mExt = substitute((el.att.value));
+               case "asmExe" : c.mAsmExe = substitute((el.att.value));
                case "pch" : c.setPCH( substitute((el.att.value)) );
                case "getversion" : c.mGetCompilerVersion = substitute((el.att.value));
                case "section" : createCompiler(el,c);
@@ -1035,6 +1041,7 @@ class BuildTool
                   substitute(el.att.variable), substitute(el.att.target)  );
                case "options" : group.addOptions( substitute(el.att.name) );
                case "config" : group.mConfig = substitute(el.att.name);
+               case "assembler" : group.mAssembler = substitute(el.att.name);
                case "compilerflag" :
                   if (el.has.name)
                      group.addCompilerFlag( substitute(el.att.name) );
@@ -1087,7 +1094,10 @@ class BuildTool
          if (valid(el,""))
             switch(el.name)
             {
-               case "flag" : l.mFlags.push(substitute(el.att.value));
+               case "flag" :
+                   if (el.has.name)
+                      l.mFlags.push(substitute(el.att.name));
+                   l.mFlags.push(substitute(el.att.value));
                case "ext" : l.mExt = (substitute(el.att.value));
                case "outflag" : l.mOutFlag = (substitute(el.att.value));
                case "libdir" : l.mLibDir = (substitute(el.att.name));
@@ -1147,9 +1157,10 @@ class BuildTool
          if (valid(el,""))
             switch(el.name)
             {
-                case "flag" : s.mFlags.push(substitute(el.att.value));
-                case "outPre" : s.mOutPre = substitute(el.att.value);
-                case "outPost" : s.mOutPost = substitute(el.att.value);
+                case "flag" :
+                    if (el.has.name)
+                       s.mFlags.push(substitute(el.att.name));
+                    s.mFlags.push(substitute(el.att.value));
                 case "exe" : s.mExe = substitute((el.att.name));
             }
       }
@@ -1157,7 +1168,6 @@ class BuildTool
       return s;
    }
 
-
    public function createStripper(inXML:XmlAccess,inBase:Stripper):Stripper
    {
       var s = (inBase!=null && !inXML.has.replace) ? inBase :
@@ -1167,7 +1177,10 @@ class BuildTool
          if (valid(el,""))
             switch(el.name)
             {
-                case "flag" : s.mFlags.push(substitute(el.att.value));
+                case "flag" :
+                    if (el.has.name)
+                       s.mFlags.push(substitute(el.att.name));
+                    s.mFlags.push(substitute(el.att.value));
                 case "exe" : s.mExe = substitute((el.att.name));
             }
       }
@@ -1235,7 +1248,10 @@ class BuildTool
                          target.mLibs.push(lib);
                   }
 
-               case "flag" : target.mFlags.push( substitute(el.att.value) );
+               case "flag" :
+                   if (el.has.name)
+                      target.mFlags.push( substitute(el.att.name) );
+                   target.mFlags.push( substitute(el.att.value) );
                case "depend" : target.mDepends.push( substitute(el.att.name) );
                case "vflag" :
                   target.mFlags.push( substitute(el.att.name) );
@@ -1596,8 +1612,8 @@ class BuildTool
       {
          Setup.initHXCPPConfig(defines);
          Setup.setupEmscripten(defines);
-         var node = defines.get("EMSCRIPTEN_NODE_JS");
-         Log.v( node==null ? "EMSCRIPTEN_NODE_JS undefined, using 'node'" : 'Using $node from EMSCRIPTEN_NODE_JS');
+         var node = defines.get("EMSDK_NODE");
+         Log.v( node==null ? "EMSDK_NODE undefined, using 'node'" : 'Using $node from EMSDK_NODE');
          if (node=="" || node==null)
             node = "node";
 
@@ -2200,6 +2216,13 @@ class BuildTool
       }
    }
 
+   function dumpDefs()
+   {
+      Sys.println("Defines:");
+      for(k in mDefines.keys())
+         Sys.println('  $k=${mDefines.get(k)}');
+   }
+
    function parseXML(inXML:XmlAccess,inSection:String, forceRelative:Bool)
    {
       for(el in inXML.elements)
@@ -2209,9 +2232,14 @@ class BuildTool
             switch(el.name)
             {
                case "set" :
-                  var name = substitute(el.att.name);
-                  var value = substitute(el.att.value);
-                  mDefines.set(name,value);
+                  if (el.has.name)
+                  {
+                     var name = substitute(el.att.name);
+                     var value = substitute(el.att.value);
+                     mDefines.set(name,value);
+                  }
+                  else
+                     dumpDefs();
                case "unset" :
                   var name = substitute(el.att.name);
                   mDefines.remove(name);
@@ -2331,8 +2359,8 @@ class BuildTool
    public function checkToolVersion(inVersion:String)
    {
       var ver = Std.parseInt(inVersion);
-      if (ver>3)
-         Log.error("Your version of hxcpp.n is out-of-date.  Please update.");
+      if (ver>6)
+         Log.error("Your version of hxcpp.n is out-of-date.  Please update by compiling 'haxe compile.hxml' in hxcpp/tools/hxcpp.");
    }
 
    public function resolvePath(inPath:String)
@@ -2402,6 +2430,8 @@ class BuildTool
          path = path.split("\\").join("/");
          var filename = "";
          var parts = path.split("/");
+         if (!FileSystem.exists(path))
+            Log.error("File does not exist:" + path);
          if (!FileSystem.isDirectory(path))
             filename = parts.pop();
 
diff --git a/tools/hxcpp/Compiler.hx b/tools/hxcpp/Compiler.hx
index bf3c2372f..277fed341 100644
--- a/tools/hxcpp/Compiler.hx
+++ b/tools/hxcpp/Compiler.hx
@@ -1,6 +1,7 @@
 import haxe.crypto.Md5;
 import haxe.io.Path;
 import sys.FileSystem;
+using StringTools;
 
 private class FlagInfo
 {
@@ -35,8 +36,10 @@ class Compiler
    public var mCPPFlags:Array<String>;
    public var mOBJCFlags:Array<String>;
    public var mPCHFlags:Array<String>;
+   public var mAsmFlags:Array<String>;
    public var mAddGCCIdentity:Bool;
    public var mExe:String;
+   public var mAsmExe:String;
    public var mOutFlag:String;
    public var mObjDir:String;
    public var mRelObjDir:String;
@@ -72,12 +75,14 @@ class Compiler
       mOBJCFlags = [];
       mMMFlags = [];
       mPCHFlags = [];
+      mAsmFlags = [];
       mAddGCCIdentity = false;
       mCompilerVersion = null;
       mRcExt = ".res";
       mObjDir = "obj";
       mOutFlag = "-o";
       mExe = inExe;
+      mAsmExe = inExe;
       mID = inID;
       mExt = ".o";
       mPCHExt = ".pch";
@@ -172,12 +177,13 @@ class Compiler
    function getArgs(inFile:File)
    {
       var nvcc = inFile.isNvcc();
+      var asm = inFile.isAsm();
       var isRc = mRcExe!=null && inFile.isResource();
       var args = nvcc ? inFile.mGroup.mCompilerFlags.concat( BuildTool.getNvccFlags() ) :
                        inFile.mCompilerFlags.concat(inFile.mGroup.mCompilerFlags);
       var tagFilter = inFile.getTags().split(",");
       addOptimTags(tagFilter);
-      if (!isRc)
+      if (!isRc && !asm)
          for(flag in mFlags)
             flag.add(args,tagFilter);
       var ext = mExt.toLowerCase();
@@ -191,7 +197,10 @@ class Compiler
       addIdentity(ext,args);
 
       var allowPch = false;
-      if (nvcc)
+
+      if (asm)
+         args = args.concat(mAsmFlags);
+      else if (nvcc)
          args = args.concat(mNvccFlags);
       else if (isRc)
          args = args.concat(mRcFlags);
@@ -297,7 +306,9 @@ class Compiler
       var obj_name = getObjName(inFile);
       var args = getArgs(inFile);
       var nvcc = inFile.isNvcc();
-      var exe = nvcc ? BuildTool.getNvcc() : mExe;
+      var asm = inFile.isAsm();
+      var exe = asm ? inFile.getAsmExe(mAsmExe) : nvcc ? BuildTool.getNvcc() : mExe;
+      var nasm = asm && (exe.endsWith("nasm") || exe.endsWith("nasm.exe"));
       var isRc =  mRcExe!=null && inFile.isResource();
       if (isRc)
          exe = mRcExe;
@@ -359,7 +370,7 @@ class Compiler
                args.push( (new Path( inFile.mDir + inFile.mName)).toString() );
          }
 
-         var out = nvcc ? "-o " : mOutFlag;
+         var out = (nvcc||nasm) ? "-o " : mOutFlag;
          if (out.substr(-1)==" ")
          {
             args.push(out.substr(0,out.length-1));
diff --git a/tools/hxcpp/File.hx b/tools/hxcpp/File.hx
index 7b04621a6..4b3ab33ff 100644
--- a/tools/hxcpp/File.hx
+++ b/tools/hxcpp/File.hx
@@ -44,6 +44,10 @@ class File
 
    public function isNvcc() return mGroup.mNvcc;
 
+   public function isAsm() return mName.endsWith(".asm");
+
+   public function getAsmExe(compilerAsm:String) return mGroup.getAsmExe(compilerAsm);
+
    public function isResource() return mName.endsWith(".rc");
 
    public function keep(inDefines:Map<String,String>)
diff --git a/tools/hxcpp/FileGroup.hx b/tools/hxcpp/FileGroup.hx
index f7820c8be..b88490d20 100644
--- a/tools/hxcpp/FileGroup.hx
+++ b/tools/hxcpp/FileGroup.hx
@@ -25,6 +25,7 @@ class FileGroup
    public var mCacheProject:String;
    public var mTags:String;
    public var mNvcc:Bool;
+   public var mAssembler:String;
    public var mObjPrefix:String;
    
    public function new(inDir:String,inId:String,inSetImportDir = false)
@@ -73,6 +74,14 @@ class FileGroup
       return Lambda.exists(mFiles, function(file:File) { return true; } );
    }
 
+   public function getAsmExe(compilerAsm:String)
+   {
+      if (mAssembler==null || mAssembler=="")
+         return compilerAsm;
+      return mAssembler;
+   }
+
+
    public function filter(defines:Map<String,String>)
    {
       var newFiles = new Map<String, File>();
diff --git a/tools/hxcpp/Setup.hx b/tools/hxcpp/Setup.hx
index 546fc7efa..1b6eb36ff 100644
--- a/tools/hxcpp/Setup.hx
+++ b/tools/hxcpp/Setup.hx
@@ -267,11 +267,12 @@ class Setup
 
    public static function setupEmscripten(ioDefines:Hash<String>)
    {
-      // Setup EMSCRIPTEN_SDK if possible - else assume developer has it in path
-      if (!ioDefines.exists("EMSCRIPTEN_SDK"))
+      // Setup EMSDK if possible - else assume developer has it in path
+      if (!ioDefines.exists("EMSDK") )
       {
          var home = ioDefines.get("HXCPP_HOME");
          var file = home + "/.emscripten";
+         Log.v('No EMSDK provided, checking $file');
          if (FileSystem.exists(file))
          {
             var content = sys.io.File.getContent(file);
@@ -285,16 +286,33 @@ class Setup
                   var val= value.matched(2);
                   if (name=="EMSCRIPTEN_ROOT")
                   {
-                     ioDefines.set("EMSCRIPTEN_SDK", val);
+                     ioDefines.set("EMSDK", val);
                   }
                   if (name=="PYTHON")
-                     ioDefines.set("EMSCRIPTEN_PYTHON", val);
+                     ioDefines.set("EMSDK_PYTHON", val);
                   if (name=="NODE_JS")
-                     ioDefines.set("EMSCRIPTEN_NODE_JS", val);
+                     ioDefines.set("EMSDK_NODE", val);
                }
             }
          }
       }
+      else
+      {
+         Log.v('Using provided EMSDK ${ioDefines.get("EMSDK")}');
+      }
+
+      if (!ioDefines.exists("EMSDK_PYTHON"))
+      {
+         Log.v("No EMSDK_PYTHON provided, using 'python'");
+      }
+      else
+         Log.v('Using provided EMSDK_PYTHON ${ioDefines.get("EMSDK_PYTHON")}');
+
+      if (!ioDefines.exists("EMSDK_NODE"))
+      {
+         Log.v("No EMSDK_NODE provided, using 'node'");
+         ioDefines.set("EMSDK_NODE", "node");
+      }
    }