diff options
-rwxr-xr-x | src/embind/embind.js | 53 | ||||
-rwxr-xr-x | system/include/emscripten/bind.h | 167 |
2 files changed, 98 insertions, 122 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js index e0abe6f1..f850c73f 100755 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -386,26 +386,15 @@ function __embind_register_tuple(rawType, name, rawConstructor, rawDestructor) { }); } -function copyMemberPointer(memberPointer, memberPointerSize) { - var copy = _malloc(memberPointerSize); - if (!copy) { - throw new Error('Failed to allocate member pointer copy'); - } - _memcpy(copy, memberPointer, memberPointerSize); - return copy; -} - function __embind_register_tuple_element( rawTupleType, rawType, getter, setter, - memberPointerSize, - memberPointer + context ) { getter = FUNCTION_TABLE[getter]; setter = FUNCTION_TABLE[setter]; - memberPointer = copyMemberPointer(memberPointer, memberPointerSize); var tupleType = requireRegisteredType(rawTupleType, 'tuple'); var index = tupleType.elements.length; @@ -416,11 +405,11 @@ function __embind_register_tuple_element( type = type[0]; tupleType.elements[index] = { read: function(ptr) { - return type.fromWireType(getter(ptr, memberPointer)); + return type.fromWireType(getter(context, ptr)); }, write: function(ptr, o) { var destructors = []; - setter(ptr, memberPointer, type.toWireType(destructors, o)); + setter(context, ptr, type.toWireType(destructors, o)); runDestructors(destructors); } }; @@ -432,29 +421,27 @@ function __embind_register_tuple_element_accessor( rawTupleType, rawElementType, rawStaticGetter, - getterSize, - getter, + getterContext, rawStaticSetter, - setterSize, - setter + setterContext ) { var tupleType = requireRegisteredType(rawTupleType, 'tuple'); rawStaticGetter = FUNCTION_TABLE[rawStaticGetter]; - getter = copyMemberPointer(getter, getterSize); rawStaticSetter = FUNCTION_TABLE[rawStaticSetter]; - setter = copyMemberPointer(setter, setterSize); whenDependentTypesAreResolved([], [rawElementType], function(elementType) { elementType = elementType[0]; tupleType.elements.push({ read: function(ptr) { - return elementType.fromWireType(rawStaticGetter(ptr, HEAP32[getter >> 2])); + return elementType.fromWireType(rawStaticGetter( + getterContext, + ptr)); }, write: function(ptr, o) { var destructors = []; rawStaticSetter( + setterContext, ptr, - HEAP32[setter >> 2], elementType.toWireType(destructors, o)); runDestructors(destructors); } @@ -512,24 +499,22 @@ function __embind_register_struct_field( rawFieldType, rawGetter, rawSetter, - memberPointerSize, - memberPointer + context ) { var structType = requireRegisteredType(rawStructType, 'struct'); fieldName = Pointer_stringify(fieldName); rawGetter = FUNCTION_TABLE[rawGetter]; rawSetter = FUNCTION_TABLE[rawSetter]; - memberPointer = copyMemberPointer(memberPointer, memberPointerSize); // TODO: test incomplete registration of value structs whenDependentTypesAreResolved([], [rawFieldType], function(fieldType) { fieldType = fieldType[0]; structType.fields[fieldName] = { read: function(ptr) { - return fieldType.fromWireType(rawGetter(ptr, memberPointer)); + return fieldType.fromWireType(rawGetter(context, ptr)); }, write: function(ptr, o) { var destructors = []; - rawSetter(ptr, memberPointer, fieldType.toWireType(destructors, o)); + rawSetter(context, ptr, fieldType.toWireType(destructors, o)); runDestructors(destructors); } }; @@ -989,13 +974,11 @@ function __embind_register_class_function( argCount, rawArgTypesAddr, // [ReturnType, ThisType, Args...] rawInvoker, - memberFunctionSize, - memberFunction + context ) { var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); methodName = Pointer_stringify(methodName); rawInvoker = FUNCTION_TABLE[rawInvoker]; - memberFunction = copyMemberPointer(memberFunction, memberFunctionSize); whenDependentTypesAreResolved([], [rawClassType], function(classType) { classType = classType[0]; @@ -1015,7 +998,7 @@ function __embind_register_class_function( var destructors = []; var args = new Array(argCount + 1); - args[0] = memberFunction; + args[0] = context; args[1] = argTypes[1].toWireType(destructors, this); for (var i = 2; i < argCount; ++i) { args[i] = argTypes[i].toWireType(destructors, arguments[i - 2]); @@ -1064,13 +1047,11 @@ function __embind_register_class_property( rawFieldType, getter, setter, - memberPointerSize, - memberPointer + context ) { fieldName = Pointer_stringify(fieldName); getter = FUNCTION_TABLE[getter]; setter = FUNCTION_TABLE[setter]; - memberPointer = copyMemberPointer(memberPointer, memberPointerSize); whenDependentTypesAreResolved([], [rawClassType], function(classType) { classType = classType[0]; var humanName = classType.name + '.' + fieldName; @@ -1091,12 +1072,12 @@ function __embind_register_class_property( Object.defineProperty(classType.registeredClass.instancePrototype, fieldName, { get: function() { var ptr = validateThis(this, classType, humanName + ' getter'); - return fieldType.fromWireType(getter(ptr, memberPointer)); + return fieldType.fromWireType(getter(context, ptr)); }, set: function(v) { var ptr = validateThis(this, classType, humanName + ' setter'); var destructors = []; - setter(ptr, memberPointer, fieldType.toWireType(destructors, v)); + setter(context, ptr, fieldType.toWireType(destructors, v)); runDestructors(destructors); }, enumerable: true diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 211c67c0..947f0b30 100755 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -73,18 +73,15 @@ namespace emscripten { TYPEID elementType, GenericFunction getter, GenericFunction setter, - size_t memberPointerSize, - void* memberPointer); + void* context); void _embind_register_tuple_element_accessor( TYPEID tupleType, TYPEID elementType, GenericFunction staticGetter, - size_t getterSize, - void* getter, + void* getterContext, GenericFunction staticSetter, - size_t setterSize, - void* setter); + void* setterContext); void _embind_register_struct( TYPEID structType, @@ -98,8 +95,7 @@ namespace emscripten { TYPEID fieldType, GenericFunction getter, GenericFunction setter, - size_t memberPointerSize, - void* memberPointer); + void* context); void _embind_register_smart_ptr( TYPEID pointerType, @@ -135,8 +131,7 @@ namespace emscripten { unsigned argCount, TYPEID argTypes[], GenericFunction invoker, - size_t memberFunctionSize, - void* memberFunction); + void* context); void _embind_register_class_property( TYPEID classType, @@ -144,8 +139,7 @@ namespace emscripten { TYPEID fieldType, GenericFunction getter, GenericFunction setter, - size_t memberPointerSize, - void* memberPointer); + void* context); void _embind_register_class_class_function( TYPEID classType, @@ -354,15 +348,15 @@ namespace emscripten { typedef typename MemberBinding::WireType WireType; static WireType getWire( - const ClassType& ptr, - const MemberPointer& field + const MemberPointer& field, + const ClassType& ptr ) { return MemberBinding::toWireType(ptr.*field); } static void setWire( - ClassType& ptr, const MemberPointer& field, + ClassType& ptr, WireType value ) { ptr.*field = MemberBinding::fromWireType(value); @@ -370,22 +364,31 @@ namespace emscripten { template<typename Getter> static WireType propertyGet( - const ClassType& ptr, - const Getter& getter + const Getter& getter, + const ClassType& ptr ) { return MemberBinding::toWireType(getter(ptr)); } template<typename Setter> static void propertySet( - ClassType& ptr, const Setter& setter, + ClassType& ptr, WireType value ) { setter(ptr, MemberBinding::fromWireType(value)); } }; + // TODO: This could do a reinterpret-cast if sizeof(T) === sizeof(void*) + template<typename T> + inline void* getContext(const T& t) { + // not a leak because this is called once per binding + void* p = malloc(sizeof(T)); + assert(p); + memcpy(p, &t, sizeof(T)); + return p; + } } //////////////////////////////////////////////////////////////////////////////// @@ -396,79 +399,75 @@ namespace emscripten { class value_tuple { public: value_tuple(const char* name) { - internal::_embind_register_tuple( - internal::TypeID<ClassType>::get(), + using namespace internal; + _embind_register_tuple( + TypeID<ClassType>::get(), name, - reinterpret_cast<internal::GenericFunction>(&internal::raw_constructor<ClassType>), - reinterpret_cast<internal::GenericFunction>(&internal::raw_destructor<ClassType>)); + reinterpret_cast<GenericFunction>(&raw_constructor<ClassType>), + reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>)); } template<typename ElementType> value_tuple& element(ElementType ClassType::*field) { - internal::_embind_register_tuple_element( - internal::TypeID<ClassType>::get(), - internal::TypeID<ElementType>::get(), - reinterpret_cast<internal::GenericFunction>(&internal::MemberAccess<ClassType, ElementType>::getWire), - reinterpret_cast<internal::GenericFunction>(&internal::MemberAccess<ClassType, ElementType>::setWire), - sizeof(field), - &field); - + using namespace internal; + _embind_register_tuple_element( + TypeID<ClassType>::get(), + TypeID<ElementType>::get(), + reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, ElementType>::getWire), + reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, ElementType>::setWire), + getContext(field)); return *this; } template<typename ElementType> value_tuple& element(ElementType (*getter)(const ClassType&), void (*setter)(ClassType&, ElementType)) { - internal::_embind_register_tuple_element_accessor( - internal::TypeID<ClassType>::get(), - internal::TypeID<ElementType>::get(), - reinterpret_cast<internal::GenericFunction>(&internal::MemberAccess<ClassType, ElementType>::template propertyGet<ElementType(const ClassType&)>), - sizeof(getter), - &getter, - reinterpret_cast<internal::GenericFunction>(&internal::MemberAccess<ClassType, ElementType>::template propertySet<void(ClassType&, ElementType)>), - sizeof(setter), - &setter); + using namespace internal; + _embind_register_tuple_element_accessor( + TypeID<ClassType>::get(), + TypeID<ElementType>::get(), + reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, ElementType>::template propertyGet<ElementType(*)(const ClassType&)>), + getContext(getter), + reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, ElementType>::template propertySet<void(*)(ClassType&, ElementType)>), + getContext(setter)); return *this; } template<typename ElementType> value_tuple& element(ElementType (*getter)(const ClassType&), void (*setter)(ClassType&, const ElementType&)) { - internal::_embind_register_tuple_element_accessor( - internal::TypeID<ClassType>::get(), - internal::TypeID<ElementType>::get(), - reinterpret_cast<internal::GenericFunction>(&internal::MemberAccess<ClassType, ElementType>::template propertyGet<ElementType(const ClassType&)>), - sizeof(getter), - &getter, - reinterpret_cast<internal::GenericFunction>(&internal::MemberAccess<ClassType, ElementType>::template propertySet<void(ClassType&, ElementType)>), - sizeof(setter), - &setter); + using namespace internal; + _embind_register_tuple_element_accessor( + TypeID<ClassType>::get(), + TypeID<ElementType>::get(), + reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, ElementType>::template propertyGet<ElementType(*)(const ClassType&)>), + getContext(getter), + reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, ElementType>::template propertySet<void(*)(ClassType&, ElementType)>), + getContext(setter)); return *this; } template<typename ElementType> value_tuple& element(ElementType (*getter)(const ClassType&), void (*setter)(ClassType&, const ElementType&&)) { - internal::_embind_register_tuple_element_accessor( - internal::TypeID<ClassType>::get(), - internal::TypeID<ElementType>::get(), - reinterpret_cast<internal::GenericFunction>(&internal::MemberAccess<ClassType, ElementType>::template propertyGet<ElementType(const ClassType&)>), - sizeof(getter), - &getter, - reinterpret_cast<internal::GenericFunction>(&internal::MemberAccess<ClassType, ElementType>::template propertySet<void(ClassType&, ElementType)>), - sizeof(setter), - &setter); + using namespace internal; + _embind_register_tuple_element_accessor( + TypeID<ClassType>::get(), + TypeID<ElementType>::get(), + reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, ElementType>::template propertyGet<ElementType(*)(const ClassType&)>), + getContext(getter), + reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, ElementType>::template propertySet<void(*)(ClassType&, ElementType)>), + getContext(setter)); return *this; } template<typename ElementType> value_tuple& element(ElementType (*getter)(const ClassType&), void (*setter)(ClassType&, ElementType&)) { - internal::_embind_register_tuple_element_accessor( - internal::TypeID<ClassType>::get(), - internal::TypeID<ElementType>::get(), - reinterpret_cast<internal::GenericFunction>(&internal::MemberAccess<ClassType, ElementType>::template propertyGet<ElementType(const ClassType&)>), - sizeof(getter), - &getter, - reinterpret_cast<internal::GenericFunction>(&internal::MemberAccess<ClassType, ElementType>::template propertySet<void(ClassType&, ElementType)>), - sizeof(setter), - &setter); + using namespace internal; + _embind_register_tuple_element_accessor( + TypeID<ClassType>::get(), + TypeID<ElementType>::get(), + reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, ElementType>::template propertyGet<ElementType(*)(const ClassType&)>), + getContext(getter), + reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, ElementType>::template propertySet<void(*)(ClassType&, ElementType)>), + getContext(setter)); return *this; } }; @@ -481,24 +480,24 @@ namespace emscripten { class value_struct { public: value_struct(const char* name) { - internal::_embind_register_struct( - internal::TypeID<ClassType>::get(), + using namespace internal; + _embind_register_struct( + TypeID<ClassType>::get(), name, - reinterpret_cast<internal::GenericFunction>(&internal::raw_constructor<ClassType>), - reinterpret_cast<internal::GenericFunction>(&internal::raw_destructor<ClassType>)); + reinterpret_cast<GenericFunction>(&raw_constructor<ClassType>), + reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>)); } template<typename FieldType> value_struct& field(const char* fieldName, FieldType ClassType::*field) { - internal::_embind_register_struct_field( - internal::TypeID<ClassType>::get(), + using namespace internal; + _embind_register_struct_field( + TypeID<ClassType>::get(), fieldName, - internal::TypeID<FieldType>::get(), - reinterpret_cast<internal::GenericFunction>(&internal::MemberAccess<ClassType, FieldType>::getWire), - reinterpret_cast<internal::GenericFunction>(&internal::MemberAccess<ClassType, FieldType>::setWire), - sizeof(field), - &field); - + TypeID<FieldType>::get(), + reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::getWire), + reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::setWire), + getContext(field)); return *this; } }; @@ -783,8 +782,7 @@ namespace emscripten { args.count, args.types, reinterpret_cast<GenericFunction>(&MethodInvoker<decltype(memberFunction), ReturnType, ClassType*, Args...>::invoke), - sizeof(memberFunction), - &memberFunction); + getContext(memberFunction)); return *this; } @@ -799,8 +797,7 @@ namespace emscripten { args.count, args.types, reinterpret_cast<GenericFunction>(&MethodInvoker<decltype(memberFunction), ReturnType, const ClassType*, Args...>::invoke), - sizeof(memberFunction), - &memberFunction); + getContext(memberFunction)); return *this; } @@ -815,8 +812,7 @@ namespace emscripten { args.count, args.types, reinterpret_cast<GenericFunction>(&FunctionInvoker<decltype(function), ReturnType, ThisType, Args...>::invoke), - sizeof(function), - &function); + getContext(function)); return *this; } @@ -830,8 +826,7 @@ namespace emscripten { TypeID<FieldType>::get(), reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::getWire), reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::setWire), - sizeof(field), - &field); + getContext(field)); return *this; } |