aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/embind/embind.js23
-rw-r--r--system/include/emscripten/bind.h64
2 files changed, 83 insertions, 4 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js
index 6ec07cd9..23248335 100644
--- a/src/embind/embind.js
+++ b/src/embind/embind.js
@@ -1,4 +1,4 @@
-/*global Module*/
+/*global Module, asm*/
/*global _malloc, _free, _memcpy*/
/*global FUNCTION_TABLE, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64*/
/*global readLatin1String*/
@@ -708,10 +708,27 @@ function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cp
return invokerFunction;
}
-function __embind_register_function(name, argCount, rawArgTypesAddr, rawInvoker, fn) {
+function requireFunction(signature, rawFunction) {
+ signature = readLatin1String(signature);
+ var fp;
+ if (typeof FUNCTION_TABLE === "undefined") {
+ // asm.js style
+ fp = asm['FUNCTION_TABLE_' + signature](rawFunction);
+ } else {
+ fp = FUNCTION_TABLE[rawFunction];
+ }
+
+ if (typeof fp !== "function") {
+ throwBindingError("unknown function pointer with signature " + signature + ": " + rawFunction);
+ }
+ return fp;
+}
+
+function __embind_register_function(name, argCount, rawArgTypesAddr, signature, rawInvoker, fn) {
var argTypes = heap32VectorToArray(argCount, rawArgTypesAddr);
name = readLatin1String(name);
- rawInvoker = FUNCTION_TABLE[rawInvoker];
+
+ rawInvoker = requireFunction(signature, rawInvoker);
exposePublicSymbol(name, function() {
throwUnboundTypeError('Cannot call ' + name + ' due to unbound types', argTypes);
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h
index 872f279b..8a8b7d69 100644
--- a/system/include/emscripten/bind.h
+++ b/system/include/emscripten/bind.h
@@ -20,6 +20,8 @@ namespace emscripten {
namespace internal {
typedef long GenericEnumValue;
+ typedef void (*GenericFunction)();
+
// Implemented in JavaScript. Don't call these directly.
extern "C" {
void _embind_fatal_error(
@@ -70,6 +72,7 @@ namespace emscripten {
const char* name,
unsigned argCount,
TYPEID argTypes[],
+ const char* signature,
GenericFunction invoker,
GenericFunction function);
@@ -291,6 +294,63 @@ namespace emscripten {
}
////////////////////////////////////////////////////////////////////////////////
+ // SignatureCode, SignatureString
+ ////////////////////////////////////////////////////////////////////////////////
+
+ namespace internal {
+ template<typename T>
+ struct SignatureCode {
+ static constexpr char get() {
+ return 'i';
+ }
+ };
+
+ template<>
+ struct SignatureCode<void> {
+ static constexpr char get() {
+ return 'v';
+ }
+ };
+
+ template<>
+ struct SignatureCode<float> {
+ static constexpr char get() {
+ return 'd';
+ }
+ };
+
+ template<>
+ struct SignatureCode<double> {
+ static constexpr char get() {
+ return 'd';
+ }
+ };
+
+ template<typename... T>
+ struct SignatureString;
+
+ template<>
+ struct SignatureString<> {
+ char c = 0;
+ };
+
+ template<typename First, typename... Rest>
+ struct SignatureString<First, Rest...> {
+ constexpr SignatureString()
+ : c(SignatureCode<First>::get())
+ {}
+ char c;
+ SignatureString<Rest...> rest;
+ };
+
+ template<typename Return, typename... Args>
+ const char* getSignature(Return (*)(Args...)) {
+ static constexpr SignatureString<Return, Args...> sig;
+ return &sig.c;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
////////////////////////////////////////////////////////////////////////////////
@@ -302,11 +362,13 @@ namespace emscripten {
void function(const char* name, ReturnType (*fn)(Args...), Policies...) {
using namespace internal;
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
+ auto invoker = &Invoker<ReturnType, Args...>::invoke;
_embind_register_function(
name,
args.count,
args.types,
- reinterpret_cast<GenericFunction>(&Invoker<ReturnType, Args...>::invoke),
+ getSignature(invoker),
+ reinterpret_cast<GenericFunction>(invoker),
reinterpret_cast<GenericFunction>(fn));
}