diff options
author | Chad Austin <chad@imvu.com> | 2013-08-29 13:39:54 -0700 |
---|---|---|
committer | Bruce Mitchener <bruce.mitchener@gmail.com> | 2014-02-04 16:16:10 +0700 |
commit | 1511e68f617e555b5342fe9df693eed07ffac8cb (patch) | |
tree | 5c3611d9e2da0530e42b5f79edcd2b2caf21531c /system | |
parent | 04b624f10d7f040e5e9551e9c956c4b0ca7c66b0 (diff) |
Fix a possible memory corruption bug when using val::as
Diffstat (limited to 'system')
-rw-r--r-- | system/include/emscripten/val.h | 32 | ||||
-rw-r--r-- | system/include/emscripten/wire.h | 1 |
2 files changed, 29 insertions, 4 deletions
diff --git a/system/include/emscripten/val.h b/system/include/emscripten/val.h index b712d164..5a04d30f 100644 --- a/system/include/emscripten/val.h +++ b/system/include/emscripten/val.h @@ -11,6 +11,11 @@ namespace emscripten { void _emval_register_symbol(const char*); typedef struct _EM_VAL* EM_VAL; + + // TODO: functions returning this are reinterpret_cast + // into the correct return type. this needs some thought + // for asm.js. + typedef void _POLYMORPHIC_RESULT; void _emval_incref(EM_VAL value); void _emval_decref(EM_VAL value); @@ -32,7 +37,8 @@ namespace emscripten { EM_VAL _emval_get_module_property(const char* name); EM_VAL _emval_get_property(EM_VAL object, EM_VAL key); void _emval_set_property(EM_VAL object, EM_VAL key, EM_VAL value); - void _emval_as(EM_VAL value, TYPEID returnType); + _POLYMORPHIC_RESULT _emval_as(EM_VAL value, TYPEID returnType, EM_VAL* runDestructors); + EM_VAL _emval_call( EM_VAL value, unsigned argCount, @@ -94,6 +100,22 @@ namespace emscripten { toWireType(std::forward<Args>(args))...); } }; + + struct DestructorsRunner { + public: + DestructorsRunner(EM_VAL v) + : dr(v) + {} + DestructorsRunner(const DestructorsRunner&) = delete; + void operator=(const DestructorsRunner&) = delete; + ~DestructorsRunner() { + EM_VAL rv = _emval_call(dr, 0, 0); + _emval_decref(rv); // TODO: if we had an _emval_call_void we wouldn't need this + _emval_decref(dr); + } + private: + EM_VAL dr; + }; } #define EMSCRIPTEN_SYMBOL(name) \ @@ -262,11 +284,13 @@ namespace emscripten { typedef typename BT::WireType (*TypedAs)( EM_VAL value, - TYPEID returnType); + TYPEID returnType, + EM_VAL* runDestructors); TypedAs typedAs = reinterpret_cast<TypedAs>(&_emval_as); - typename BT::WireType wt = typedAs(handle, TypeID<T>::get()); - WireDeleter<T> deleter(wt); + EM_VAL runDestructors; + typename BT::WireType wt = typedAs(handle, TypeID<T>::get(), &runDestructors); + DestructorsRunner dr(runDestructors); return BT::fromWireType(wt); } diff --git a/system/include/emscripten/wire.h b/system/include/emscripten/wire.h index a5892216..70deb2c7 100644 --- a/system/include/emscripten/wire.h +++ b/system/include/emscripten/wire.h @@ -7,6 +7,7 @@ // // We'll call the on-the-wire type WireType. +#include <stdio.h> #include <cstdlib> #include <memory> #include <string> |