aboutsummaryrefslogtreecommitdiff
path: root/system
diff options
context:
space:
mode:
authorChad Austin <chad@imvu.com>2013-08-29 13:39:54 -0700
committerBruce Mitchener <bruce.mitchener@gmail.com>2014-02-04 16:16:10 +0700
commit1511e68f617e555b5342fe9df693eed07ffac8cb (patch)
tree5c3611d9e2da0530e42b5f79edcd2b2caf21531c /system
parent04b624f10d7f040e5e9551e9c956c4b0ca7c66b0 (diff)
Fix a possible memory corruption bug when using val::as
Diffstat (limited to 'system')
-rw-r--r--system/include/emscripten/val.h32
-rw-r--r--system/include/emscripten/wire.h1
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>