aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Austin <chad@imvu.com>2013-03-23 02:07:45 -0700
committerJukka Jylänki <jujjyl@gmail.com>2013-04-12 14:26:36 +0300
commitb7936b0a61a37b451b2e4f01cb02986d26640d35 (patch)
treecbfd7e6a04e81420193c532e962a38ad53a0cf50
parent0b8597a8dbf36b26dfb76df8d11fa7377bd810f1 (diff)
Unify 'this' handling in class functions. 'this' is just the first argument to the method. This removes several special cases and will remove even more soon.
-rwxr-xr-xsrc/embind/embind.js23
-rwxr-xr-xsystem/include/emscripten/bind.h119
2 files changed, 50 insertions, 92 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js
index ddfc4d43..d5e8659d 100755
--- a/src/embind/embind.js
+++ b/src/embind/embind.js
@@ -958,7 +958,8 @@ function validateThis(this_, classType, humanName) {
if (!this_.$$.ptr) {
throwBindingError('cannot call emscripten binding method ' + humanName + ' on deleted object');
}
-
+
+ // todo: kill this
return upcastPointer(
this_.$$.ptr,
this_.$$.ptrType.registeredClass,
@@ -969,8 +970,7 @@ function __embind_register_class_function(
rawClassType,
methodName,
argCount,
- rawArgTypesAddr,
- isConst,
+ rawArgTypesAddr, // [ReturnType, ThisType, Args...]
rawInvoker,
memberFunctionSize,
memberFunction
@@ -990,21 +990,18 @@ function __embind_register_class_function(
whenDependentTypesAreResolved([], rawArgTypes, function(argTypes) {
classType.registeredClass.instancePrototype[methodName] = function() {
- if (arguments.length !== argCount - 1) {
- throwBindingError('emscripten binding method ' + humanName + ' called with ' + arguments.length + ' arguments, expected ' + (argCount-1));
+ if (arguments.length !== argCount - 2) {
+ throwBindingError(humanName + ' called with ' + arguments.length + ' arguments, expected ' + (argCount-1));
}
- var ptr = validateThis(this, classType, humanName);
- if (!isConst && this.$$.ptrType.isConst) {
- throwBindingError('Cannot call non-const method ' + humanName + ' on const reference');
- }
+ validateThis(this, classType, humanName);
var destructors = [];
var args = new Array(argCount + 1);
- args[0] = ptr;
- args[1] = memberFunction;
- for (var i = 1; i < argCount; ++i) {
- args[i + 1] = argTypes[i].toWireType(destructors, arguments[i - 1]);
+ args[0] = memberFunction;
+ args[1] = argTypes[1].toWireType(destructors, this);
+ for (var i = 2; i < argCount; ++i) {
+ args[i] = argTypes[i].toWireType(destructors, arguments[i - 2]);
}
var rv = rawInvoker.apply(null, args);
rv = argTypes[0].fromWireType(rv);
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h
index ad7e7b35..76ae7df6 100755
--- a/system/include/emscripten/bind.h
+++ b/system/include/emscripten/bind.h
@@ -132,7 +132,6 @@ namespace emscripten {
const char* methodName,
unsigned argCount,
TYPEID argTypes[],
- bool isConst,
GenericFunction invoker,
size_t memberFunctionSize,
void* memberFunction);
@@ -186,6 +185,7 @@ namespace emscripten {
static constexpr int index = 0;
};
+ /*
template<typename Slot>
struct allow_raw_pointer {
template<typename InputType, int Index>
@@ -197,6 +197,7 @@ namespace emscripten {
>::type type;
};
};
+ */
// whitelist all raw pointers
struct allow_raw_pointers {
@@ -210,6 +211,11 @@ namespace emscripten {
};
};
+ // this is temporary until arg policies are reworked
+ template<typename Slot>
+ struct allow_raw_pointer : public allow_raw_pointers {
+ };
+
namespace internal {
template<typename ReturnType, typename... Args>
struct Invoker {
@@ -278,87 +284,62 @@ namespace emscripten {
delete ptr;
}
- template<typename ClassType, typename ReturnType, typename... Args>
+ template<typename FunctionPointerType, typename ReturnType, typename ThisType, typename... Args>
struct FunctionInvoker {
- typedef ReturnType (*FunctionPointer)(ClassType& ct, Args...);
static typename internal::BindingType<ReturnType>::WireType invoke(
- ClassType* ptr,
- FunctionPointer* function,
+ FunctionPointerType* function,
+ typename internal::BindingType<ThisType>::WireType wireThis,
typename internal::BindingType<Args>::WireType... args
) {
return internal::BindingType<ReturnType>::toWireType(
- (*function)(*ptr, internal::BindingType<Args>::fromWireType(args)...)
+ (*function)(
+ internal::BindingType<ThisType>::fromWireType(wireThis),
+ internal::BindingType<Args>::fromWireType(args)...)
);
}
};
- template<typename ClassType, typename... Args>
- struct FunctionInvoker<ClassType, void, Args...> {
- typedef void (*FunctionPointer)(ClassType& ct, Args...);
+ template<typename FunctionPointerType, typename ThisType, typename... Args>
+ struct FunctionInvoker<FunctionPointerType, void, ThisType, Args...> {
static void invoke(
- ClassType* ptr,
- FunctionPointer* function,
+ FunctionPointerType* function,
+ typename internal::BindingType<ThisType>::WireType wireThis,
typename internal::BindingType<Args>::WireType... args
) {
- (*function)(*ptr, internal::BindingType<Args>::fromWireType(args)...);
+ (*function)(
+ internal::BindingType<ThisType>::fromWireType(wireThis),
+ internal::BindingType<Args>::fromWireType(args)...);
}
};
- template<typename ClassType, typename ReturnType, typename... Args>
+ template<typename MemberPointer,
+ typename ReturnType,
+ typename ThisType,
+ typename... Args>
struct MethodInvoker {
- typedef ReturnType (ClassType::*MemberPointer)(Args...);
- static typename internal::BindingType<ReturnType>::WireType invoke(
- ClassType* ptr,
- const MemberPointer& method,
- typename internal::BindingType<Args>::WireType... args
- ) {
- return internal::BindingType<ReturnType>::toWireType(
- (ptr->*method)(
- internal::BindingType<Args>::fromWireType(args)...
- )
- );
- }
- };
-
- template<typename ClassType, typename... Args>
- struct MethodInvoker<ClassType, void, Args...> {
- typedef void (ClassType::*MemberPointer)(Args...);
- static void invoke(
- ClassType* ptr,
- const MemberPointer& method,
- typename internal::BindingType<Args>::WireType... args
- ) {
- return (ptr->*method)(
- internal::BindingType<Args>::fromWireType(args)...
- );
- }
- };
-
- template<typename ClassType, typename ReturnType, typename... Args>
- struct ConstMethodInvoker {
- typedef ReturnType (ClassType::*MemberPointer)(Args...) const;
static typename internal::BindingType<ReturnType>::WireType invoke(
- const ClassType* ptr,
const MemberPointer& method,
+ typename internal::BindingType<ThisType>::WireType wireThis,
typename internal::BindingType<Args>::WireType... args
) {
return internal::BindingType<ReturnType>::toWireType(
- (ptr->*method)(
+ (internal::BindingType<ThisType>::fromWireType(wireThis)->*method)(
internal::BindingType<Args>::fromWireType(args)...
)
);
}
};
- template<typename ClassType, typename... Args>
- struct ConstMethodInvoker<ClassType, void, Args...> {
- typedef void (ClassType::*MemberPointer)(Args...) const;
+ template<typename MemberPointer,
+ typename ThisType,
+ typename... Args>
+ struct MethodInvoker<MemberPointer, void, ThisType, Args...> {
static void invoke(
- const ClassType* ptr,
const MemberPointer& method,
+ typename internal::BindingType<ThisType>::WireType wireThis,
typename internal::BindingType<Args>::WireType... args
) {
- return (ptr->*method)(
+ return (internal::BindingType<ThisType>::fromWireType(wireThis)->*method)(
internal::BindingType<Args>::fromWireType(args)...
);
}
@@ -793,14 +774,13 @@ namespace emscripten {
class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...), Policies...) {
using namespace internal;
- typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
+ typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<ClassType>, Args...> args;
_embind_register_class_function(
TypeID<ClassType>::get(),
methodName,
args.count,
args.types,
- false,
- reinterpret_cast<GenericFunction>(&MethodInvoker<ClassType, ReturnType, Args...>::invoke),
+ reinterpret_cast<GenericFunction>(&MethodInvoker<decltype(memberFunction), ReturnType, ClassType*, Args...>::invoke),
sizeof(memberFunction),
&memberFunction);
return *this;
@@ -810,48 +790,29 @@ namespace emscripten {
class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...) const, Policies...) {
using namespace internal;
- typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
+ typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<const ClassType>, Args...> args;
_embind_register_class_function(
TypeID<ClassType>::get(),
methodName,
args.count,
args.types,
- true,
- reinterpret_cast<GenericFunction>(&ConstMethodInvoker<ClassType, ReturnType, Args...>::invoke),
+ reinterpret_cast<GenericFunction>(&MethodInvoker<decltype(memberFunction), ReturnType, const ClassType*, Args...>::invoke),
sizeof(memberFunction),
&memberFunction);
return *this;
}
- template<typename ReturnType, typename... Args, typename... Policies>
- class_& function(const char* methodName, ReturnType (*function)(ClassType& ptr, Args...), Policies...) {
- using namespace internal;
-
- typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
- _embind_register_class_function(
- TypeID<ClassType>::get(),
- methodName,
- args.count,
- args.types,
- false,
- reinterpret_cast<GenericFunction>(&FunctionInvoker<ClassType, ReturnType, Args...>::invoke),
- sizeof(function),
- &function);
- return *this;
- }
-
- template<typename ReturnType, typename... Args, typename... Policies>
- class_& function(const char* methodName, ReturnType (*function)(const ClassType& ptr, Args...), Policies...) {
+ template<typename ReturnType, typename ThisType, typename... Args, typename... Policies>
+ class_& function(const char* methodName, ReturnType (*function)(ThisType, Args...), Policies...) {
using namespace internal;
- typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
+ typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, ThisType, Args...> args;
_embind_register_class_function(
TypeID<ClassType>::get(),
methodName,
args.count,
args.types,
- true,
- reinterpret_cast<GenericFunction>(&FunctionInvoker<ClassType, ReturnType, Args...>::invoke),
+ reinterpret_cast<GenericFunction>(&FunctionInvoker<decltype(function), ReturnType, ClassType, Args...>::invoke),
sizeof(function),
&function);
return *this;