aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/embind/embind.js17
-rwxr-xr-xtests/embind/embind.test.js20
-rw-r--r--tests/embind/embind_test.cpp31
3 files changed, 62 insertions, 6 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js
index 16e29d9e..c298d8ba 100755
--- a/src/embind/embind.js
+++ b/src/embind/embind.js
@@ -814,10 +814,13 @@ function __embind_register_class(
if (Object.getPrototypeOf(this) !== instancePrototype) {
throw new BindingError("Use 'new' to construct " + name);
}
- var body = registeredClass.constructor_body;
- if (undefined === body) {
+ if (undefined === registeredClass.constructor_body) {
throw new BindingError(name + " has no accessible constructor");
}
+ var body = registeredClass.constructor_body[arguments.length];
+ if (undefined === body) {
+ throw new BindingError("Tried to invoke ctor of " + name + " with invalid number of parameters (" + arguments.length + ") - expected (" + Object.keys(registeredClass.constructor_body).toString() + ") parameters instead!");
+ }
return body.apply(this, arguments);
});
@@ -884,12 +887,18 @@ function __embind_register_class_constructor(
classType = classType[0];
var humanName = 'constructor ' + classType.name;
- classType.registeredClass.constructor_body = function() {
+ if (undefined === classType.registeredClass.constructor_body) {
+ classType.registeredClass.constructor_body = [];
+ }
+ if (undefined !== classType.registeredClass.constructor_body[argCount - 1]) {
+ throw new BindingError("Cannot register multiple constructors with identical number of parameters (" + (argCount-1) + ") for class '" + classType.name + "'! Overload resolution is currently only performed using the parameter count, not actual type info!");
+ }
+ classType.registeredClass.constructor_body[argCount - 1] = function() {
throwUnboundTypeError('Cannot construct ' + classType.name + ' due to unbound types', rawArgTypes);
};
whenDependentTypesAreResolved([], rawArgTypes, function(argTypes) {
- classType.registeredClass.constructor_body = function() {
+ classType.registeredClass.constructor_body[argCount - 1] = function() {
if (arguments.length !== argCount - 1) {
throwBindingError(humanName + ' called with ' + arguments.length + ' arguments, expected ' + (argCount-1));
}
diff --git a/tests/embind/embind.test.js b/tests/embind/embind.test.js
index 94d935f2..46b7646d 100755
--- a/tests/embind/embind.test.js
+++ b/tests/embind/embind.test.js
@@ -589,8 +589,24 @@ module({
assert.throws(TypeError, function() { cm.long_to_string(2147483648); });
assert.throws(TypeError, function() { cm.unsigned_long_to_string(-1); });
assert.throws(TypeError, function() { cm.unsigned_long_to_string(4294967296); });
+ });
- });
+ test("access multiple class ctors", function() {
+ var a = new cm.MultipleCtors(10);
+ assert.equal(a.WhichCtorCalled(), 1);
+ var b = new cm.MultipleCtors(20, 20);
+ assert.equal(b.WhichCtorCalled(), 2);
+ var c = new cm.MultipleCtors(30, 30, 30);
+ assert.equal(c.WhichCtorCalled(), 3);
+ a.delete();
+ b.delete();
+ c.delete();
+ });
+
+ test("wrong number of constructor arguments throws", function() {
+ assert.throws(cm.BindingError, function() { new cm.MultipleCtors(); });
+ assert.throws(cm.BindingError, function() { new cm.MultipleCtors(1,2,3,4); });
+ });
/*
test("can get templated member classes then call its member functions", function() {
@@ -1424,7 +1440,7 @@ module({
test("unbound constructor argument", function() {
assertMessage(
function() {
- new cm.HasConstructorUsingUnboundArgument;
+ new cm.HasConstructorUsingUnboundArgument(1);
},
'Cannot construct HasConstructorUsingUnboundArgument due to unbound types: UnboundClass');
});
diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp
index 470309aa..f23b9152 100644
--- a/tests/embind/embind_test.cpp
+++ b/tests/embind/embind_test.cpp
@@ -1314,6 +1314,31 @@ std::string unsigned_long_to_string(unsigned long val) {
return str;
}
+class MultipleCtors {
+public:
+ int value;
+
+ MultipleCtors(int i) {
+ value = 1;
+ assert(i == 10);
+ }
+ MultipleCtors(int i, int j) {
+ value = 2;
+ assert(i == 20);
+ assert(j == 20);
+ }
+ MultipleCtors(int i, int j, int k) {
+ value = 3;
+ assert(i == 30);
+ assert(j == 30);
+ assert(k == 30);
+ }
+
+ int WhichCtorCalled() const {
+ return value;
+ }
+};
+
EMSCRIPTEN_BINDINGS(tests) {
register_js_interface();
@@ -1759,6 +1784,12 @@ EMSCRIPTEN_BINDINGS(tests) {
function("unsigned_int_to_string", &unsigned_int_to_string);
function("long_to_string", &long_to_string);
function("unsigned_long_to_string", &unsigned_long_to_string);
+
+ class_<MultipleCtors>("MultipleCtors")
+ .constructor<int>()
+ .constructor<int, int>()
+ .constructor<int, int, int>()
+ .function("WhichCtorCalled", &MultipleCtors::WhichCtorCalled);
}
// tests for out-of-order registration