aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/embind/embind.js25
-rwxr-xr-xsystem/include/emscripten/bind.h25
-rwxr-xr-xtests/embind/embind.test.js10
-rw-r--r--tests/embind/embind_test.cpp1
4 files changed, 49 insertions, 12 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js
index ee717f4b..03af7010 100755
--- a/src/embind/embind.js
+++ b/src/embind/embind.js
@@ -1154,42 +1154,47 @@ function __embind_register_class_class_function(
}
function __embind_register_class_property(
- rawClassType,
+ classType,
fieldName,
- rawFieldType,
+ getterReturnType,
getter,
+ getterContext,
+ setterArgumentType,
setter,
- context
+ setterContext
) {
fieldName = Pointer_stringify(fieldName);
getter = FUNCTION_TABLE[getter];
setter = FUNCTION_TABLE[setter];
- whenDependentTypesAreResolved([], [rawClassType], function(classType) {
+
+ whenDependentTypesAreResolved([], [classType], function(classType) {
classType = classType[0];
var humanName = classType.name + '.' + fieldName;
Object.defineProperty(classType.registeredClass.instancePrototype, fieldName, {
get: function() {
- throwUnboundTypeError('Cannot access ' + humanName + ' due to unbound types', [rawFieldType]);
+ throwUnboundTypeError('Cannot access ' + humanName + ' due to unbound types', [getterReturnType, setterArgumentType]);
},
set: function() {
- throwUnboundTypeError('Cannot access ' + humanName + ' due to unbound types', [rawFieldType]);
+ throwUnboundTypeError('Cannot access ' + humanName + ' due to unbound types', [getterReturnType, setterArgumentType]);
},
enumerable: true,
configurable: true
});
- whenDependentTypesAreResolved([], [rawFieldType], function(fieldType) {
- fieldType = fieldType[0];
+ whenDependentTypesAreResolved([], [getterReturnType, setterArgumentType], function(types) {
+ var getterReturnType = types[0];
+ var setterArgumentType = types[1];
+
Object.defineProperty(classType.registeredClass.instancePrototype, fieldName, {
get: function() {
var ptr = validateThis(this, classType, humanName + ' getter');
- return fieldType.fromWireType(getter(context, ptr));
+ return getterReturnType.fromWireType(getter(getterContext, ptr));
},
set: function(v) {
var ptr = validateThis(this, classType, humanName + ' setter');
var destructors = [];
- setter(context, ptr, fieldType.toWireType(destructors, v));
+ setter(setterContext, ptr, setterArgumentType.toWireType(destructors, v));
runDestructors(destructors);
},
enumerable: true
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h
index 57e44c0c..d70aec91 100755
--- a/system/include/emscripten/bind.h
+++ b/system/include/emscripten/bind.h
@@ -136,10 +136,12 @@ namespace emscripten {
void _embind_register_class_property(
TYPEID classType,
const char* fieldName,
- TYPEID fieldType,
+ TYPEID getterReturnType,
GenericFunction getter,
+ void* getterContext,
+ TYPEID setterArgumentType,
GenericFunction setter,
- void* context);
+ void* setterContext);
void _embind_register_class_class_function(
TYPEID classType,
@@ -980,11 +982,30 @@ namespace emscripten {
fieldName,
TypeID<FieldType>::get(),
reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::template getWire<ClassType>),
+ getContext(field),
+ TypeID<FieldType>::get(),
reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::template setWire<ClassType>),
getContext(field));
return *this;
}
+ template<typename Getter, typename Setter>
+ class_& property(const char* fieldName, Getter getter, Setter setter) {
+ using namespace internal;
+ typedef GetterPolicy<Getter> GP;
+ typedef SetterPolicy<Setter> SP;
+ _embind_register_class_property(
+ TypeID<ClassType>::get(),
+ fieldName,
+ TypeID<typename GP::ReturnType>::get(),
+ reinterpret_cast<GenericFunction>(&GP::template get<ClassType>),
+ GP::getContext(getter),
+ TypeID<typename SP::ArgumentType>::get(),
+ reinterpret_cast<GenericFunction>(&SP::template set<ClassType>),
+ SP::getContext(setter));
+ return *this;
+ }
+
template<typename ReturnType, typename... Args, typename... Policies>
class_& class_function(const char* methodName, ReturnType (*classMethod)(Args...), Policies...) {
using namespace internal;
diff --git a/tests/embind/embind.test.js b/tests/embind/embind.test.js
index 290fed72..82dbeb25 100755
--- a/tests/embind/embind.test.js
+++ b/tests/embind/embind.test.js
@@ -837,6 +837,16 @@ module({
assert.equal(0, cm.count_emval_handles());
});
+ test("class properties can be methods", function() {
+ var a = {};
+ var b = {foo: 'foo'};
+ var c = new cm.ValHolder(a);
+ assert.equal(a, c.val);
+ c.val = b;
+ assert.equal(b, c.val);
+ c.delete();
+ });
+
test("class instance $$ property is non-enumerable", function() {
var c = new cm.ValHolder(undefined);
assert.deepEqual([], Object.keys(c));
diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp
index 1384406a..f3e2cbee 100644
--- a/tests/embind/embind_test.cpp
+++ b/tests/embind/embind_test.cpp
@@ -1527,6 +1527,7 @@ EMSCRIPTEN_BINDINGS(tests) {
.function("getConstVal", &ValHolder::getConstVal)
.function("getValConstRef", &ValHolder::getValConstRef)
.function("setVal", &ValHolder::setVal)
+ .property("val", &ValHolder::getVal, &ValHolder::setVal)
.class_function("makeConst", &ValHolder::makeConst, allow_raw_pointer<ret_val>())
.class_function("makeValHolder", &ValHolder::makeValHolder)
.class_function("some_class_method", &ValHolder::some_class_method)