aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormey <mey@imvu.com>2012-11-16 13:56:27 -0800
committerJukka Jylänki <jujjyl@gmail.com>2013-04-12 14:21:54 +0300
commite237bfd79d7ae865f7eeaccefff5e8a9c7afe309 (patch)
tree2396a6a5b10c4b502d4078c265f9a0c5b7d2d244
parent0d745fa1167007c29554da9f10bd6a92bc0d171b (diff)
Removing Functor as a specific type; folding operator call into the class definition.
-rw-r--r--src/embind/embind.js159
-rw-r--r--system/include/emscripten/bind.h62
2 files changed, 90 insertions, 131 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js
index 74afda02..ff5adf64 100644
--- a/src/embind/embind.js
+++ b/src/embind/embind.js
@@ -430,101 +430,6 @@ function __embind_register_smart_ptr(
});
}
-function __embind_register_function_ptr(
- name,
- functorType,
- returnType,
- argCount,
- argTypes,
- destructor,
- invoker
-) {
- name = Pointer_stringify(name);
- var humanName = 'functor::' + name;
-
- returnType = requireRegisteredType(returnType);
- argTypes = requireArgumentTypes(argCount, argTypes, humanName);
- destructor = FUNCTION_TABLE[destructor];
- invoker = FUNCTION_TABLE[invoker];
-
- var Handle = createNamedFunction(name, function(ptr) {
- this.count = {value: 1};
- this.functorPtr = ptr;
- });
-
- Handle.prototype['delete'] = function() {
- if (!this.functorPtr) {
- throw new BindingError(functorType.name + ' instance already deleted');
- }
-
- this.count.value -= 1;
- if(0 === this.count.value) {
- destructor(this.functorPtr);
- }
- this.functorPtr = undefined;
- };
-
- function createFunctor(ptr) {
- var h = new Handle(ptr);
-
- var invoke = function() {
- if(!this.functorPtr) {
- throw new BindingError('cannot call invoke functor ' + humanName + ' on deleted object');
- }
-
- if (arguments.length !== argCount) {
- throw new BindingError('emscripten functor ' + humanName + ' called with ' + arguments.length + ' arguments, expected ' + argCount);
- }
-
- var destructors = [];
- var args = new Array(argCount + 1);
- args[0] = this.functorPtr;
-
- for (var i = 0; i < argCount; ++i) {
- args[i + 1] = argTypes[i].toWireType(destructors, arguments[i]);
- }
-
- var rv = returnType.fromWireType(invoker.apply(null, args));
- runDestructors(destructors);
- return rv;
- }.bind(h);
-
- invoke.handle = h;
- invoke['delete'] = function() {
- this.handle.delete();
- }.bind(invoke);
- invoke.clone = function() {
- if (!this.handle.functorPtr) {
- throw new BindingError(functorType.name + ' instance already deleted');
- }
-
- var clone = createFunctor(this.handle.functorPtr);
- clone.handle.count = this.handle.count;
- clone.handle.ptr = this.handle.ptr;
-
- clone.handle.count.value += 1;
- return clone;
- }.bind(invoke);
- invoke.move = function() {
- var rv = this.clone();
- this.delete();
- return rv;
- }.bind(invoke);
-
- return invoke;
- }
-
- registerType(functorType, name, {
- name: name,
- fromWireType: function(ptr) {
- return createFunctor(ptr);
- },
- toWireType: function(destructors, o) {
- return o.handle.functorPtr;
- }
- });
-}
-
function __embind_register_vector(
vectorType,
elementType,
@@ -579,10 +484,25 @@ function __embind_register_class(
) {
name = Pointer_stringify(name);
destructor = FUNCTION_TABLE[destructor];
-
+
var Handle = createNamedFunction(name, function(ptr) {
- this.count = {value: 1};
- this.ptr = ptr;
+ var h = function() {
+ if(h.operator_call !== undefined) {
+ return h.operator_call.apply(h, arguments);
+ } else {
+ throw new BindingError(name + ' does not define call operator');
+ }
+ };
+
+ h.count = {value: 1};
+ h.ptr = ptr;
+
+ for(var prop in Handle.prototype) {
+ var dp = Object.getOwnPropertyDescriptor(Handle.prototype, prop);
+ Object.defineProperty(h, prop, dp);
+ }
+
+ return h;
});
Handle.prototype.clone = function() {
@@ -618,7 +538,7 @@ function __embind_register_class(
var constructor = createNamedFunction(name, function() {
var body = constructor.body;
- body.apply(this, arguments);
+ return body.apply(this, arguments);
});
constructor.prototype = Handle.prototype;
@@ -676,7 +596,8 @@ function __embind_register_class_constructor(
var ptr = constructor.apply(null, args);
runDestructors(destructors);
- classType.Handle.call(this, ptr);
+
+ return classType.Handle.call(this, ptr);
};
}
@@ -700,6 +621,7 @@ function __embind_register_class_method(
memberFunction = copyMemberPointer(memberFunction, memberFunctionSize);
classType.Handle.prototype[methodName] = function() {
+
if (!this.ptr) {
throw new BindingError('cannot call emscripten binding method ' + humanName + ' on deleted object');
}
@@ -737,7 +659,42 @@ function __embind_register_class_classmethod(
argTypes = requireArgumentTypes(argCount, argTypes, 'classmethod ' + humanName);
invoker = FUNCTION_TABLE[invoker];
- classType.constructor[methodName] = makeInvoker(humanName, returnType, argCount, argTypes, invoker, fn);}
+ classType.constructor[methodName] = makeInvoker(humanName, returnType, argCount, argTypes, invoker, fn);
+}
+
+function __embind_register_class_operator_call(
+ classType,
+ returnType,
+ argCount,
+ argTypes,
+ invoker
+) {
+ classType = requireRegisteredType(classType, 'class');
+ returnType = requireRegisteredType(returnType, 'method ' + humanName + ' return value');
+ argTypes = requireArgumentTypes(argCount, argTypes, 'method ' + humanName);
+ invoker = FUNCTION_TABLE[invoker];
+ var humanName = classType.name + '.' + 'operator_call';
+
+ classType.Handle.prototype.operator_call = function() {
+ if (!this.ptr) {
+ throw new BindingError('cannot call emscripten binding method ' + humanName + ' on deleted object');
+ }
+ if (arguments.length !== argCount) {
+ throw new BindingError('emscripten binding method ' + humanName + ' called with ' + arguments.length + ' arguments, expected ' + argCount);
+ }
+
+ var destructors = [];
+ var args = new Array(argCount + 1);
+ args[0] = this.ptr;
+ for (var i = 0; i < argCount; ++i) {
+ args[i + 1] = argTypes[i].toWireType(destructors, arguments[i]);
+ }
+
+ var rv = returnType.fromWireType(invoker.apply(null, args));
+ runDestructors(destructors);
+ return rv;
+ }
+}
function __embind_register_class_field(
classType,
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h
index ffbf9401..e20a5e68 100644
--- a/system/include/emscripten/bind.h
+++ b/system/include/emscripten/bind.h
@@ -100,15 +100,6 @@ namespace emscripten {
GenericFunction destructor,
GenericFunction getPointee);
- void _embind_register_function_ptr(
- const char* name,
- TYPEID functorType,
- TYPEID returnType,
- unsigned argCount,
- TYPEID argTypes[],
- GenericFunction destructor,
- GenericFunction invoker);
-
void _embind_register_vector(
TYPEID vectorType,
TYPEID elementType,
@@ -160,6 +151,14 @@ namespace emscripten {
GenericFunction invoker,
GenericFunction method);
+ void _embind_register_class_operator_call(
+ TYPEID classType,
+ TYPEID returnType,
+ unsigned argCount,
+ TYPEID argTypes[],
+ GenericFunction invoker
+ );
+
void _embind_register_enum(
TYPEID enumType,
const char* name);
@@ -255,7 +254,7 @@ namespace emscripten {
////////////////////////////////////////////////////////////////////////////////
template<typename ReturnType, typename... Args, typename... Policies>
- void function(const char* name, ReturnType (fn)(Args...)) {
+ void function(const char* name, ReturnType (fn)(Args...), Policies...) {
using namespace internal;
registerStandardTypes();
@@ -305,6 +304,15 @@ namespace emscripten {
}
};
+ template<typename FunctorType, typename... Args>
+ struct FunctorInvoker<FunctorType, void, Args...> {
+ static void invoke(
+ const FunctorType& ptr,
+ typename internal::BindingType<Args>::WireType... args
+ ) {
+ ptr(internal::BindingType<Args>::fromWireType(args)...);
+ }
+ };
template<typename ClassType, typename ReturnType, typename... Args>
struct MethodInvoker {
@@ -568,26 +576,6 @@ namespace emscripten {
}
////////////////////////////////////////////////////////////////////////////////
- // FUNCTION POINTERS
- ////////////////////////////////////////////////////////////////////////////////
- template<typename ReturnType, typename... Args, typename... Policies>
- inline void register_function_ptr(const char* name) {
- typedef std::function<ReturnType(Args...)> FunctorType;
-
- internal::registerStandardTypes();
- typename internal::WithPolicies<Policies...>::template ArgTypeList<Args...> args;
- internal::_embind_register_function_ptr(
- name,
- internal::TypeID<FunctorType>::get(),
- internal::TypeID<ReturnType>::get(),
- args.count,
- args.types,
- reinterpret_cast<internal::GenericFunction>(&internal::raw_destructor<FunctorType>),
- reinterpret_cast<internal::GenericFunction>(&internal::FunctorInvoker<FunctorType, ReturnType, Args...>::invoke)
- );
- }
-
- ////////////////////////////////////////////////////////////////////////////////
// VECTORS
////////////////////////////////////////////////////////////////////////////////
@@ -706,6 +694,20 @@ namespace emscripten {
reinterpret_cast<GenericFunction>(classMethod));
return *this;
}
+
+ template<typename ReturnType, typename... Args, typename... Policies>
+ class_& calloperator(Policies...) {
+ using namespace internal;
+
+ typename WithPolicies<Policies...>::template ArgTypeList<Args...> args;
+ _embind_register_class_operator_call(
+ TypeID<ClassType>::get(),
+ TypeID<ReturnType>::get(),
+ args.count,
+ args.types,
+ reinterpret_cast<internal::GenericFunction>(&internal::FunctorInvoker<ClassType, ReturnType, Args...>::invoke));
+ return *this;
+ }
};
////////////////////////////////////////////////////////////////////////////////