SWIGTYPE && input typemaps now assume object has been moved
Change these typemaps to assume that after a function call, the parameter has been moved. The parameter's proxy class that owns the C++ object thus has the underlying pointer set to null so the object cannot be used again and the object is deleted. Scrap new javarelease typemap and move contents into javabody typemap.
This commit is contained in:
parent
6b361bf050
commit
bf761998ed
7 changed files with 150 additions and 18 deletions
|
|
@ -610,6 +610,7 @@ CPP11_TEST_CASES += \
|
|||
cpp11_rvalue_reference \
|
||||
cpp11_rvalue_reference2 \
|
||||
cpp11_rvalue_reference3 \
|
||||
cpp11_rvalue_reference_move_input \
|
||||
cpp11_sizeof_object \
|
||||
cpp11_static_assert \
|
||||
cpp11_std_array \
|
||||
|
|
|
|||
41
Examples/test-suite/cpp11_rvalue_reference_move_input.i
Normal file
41
Examples/test-suite/cpp11_rvalue_reference_move_input.i
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
%module cpp11_rvalue_reference_move_input
|
||||
|
||||
// Testcase for testing rvalue reference input typemaps which assume the object is moved during a function call
|
||||
|
||||
#if defined(SWIGD)
|
||||
%rename(trace) debug;
|
||||
#endif
|
||||
|
||||
%include "cpp11_move_only_helper.i"
|
||||
|
||||
%rename(MoveAssign) MovableCopyable::operator=(MovableCopyable &&);
|
||||
%ignore MovableCopyable::operator=(const MovableCopyable &); // ignore copy assignment operator, keep move assignment operator
|
||||
%ignore MovableCopyable::MovableCopyable(const MovableCopyable &); // ignore copy constructor, keep the move constructor
|
||||
|
||||
%inline %{
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
bool debug = false;
|
||||
|
||||
class MovableCopyable {
|
||||
public:
|
||||
MovableCopyable(int i = 0) { if (debug) cout << "MovableCopyable(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
|
||||
|
||||
MovableCopyable(const MovableCopyable &other) { if (debug) cout << "MovableCopyable(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
|
||||
MovableCopyable & operator=(const MovableCopyable &other) { if (debug) cout << "operator=(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; return *this; }
|
||||
|
||||
MovableCopyable(MovableCopyable &&other) noexcept { if (debug) cout << "MovableCopyable(MovableCopyable &&)" << " " << this << endl; Counter::move_constructor++; }
|
||||
MovableCopyable & operator=(MovableCopyable &&other) noexcept { if (debug) cout << "operator=(MovableCopyable &&)" << " " << this << endl; Counter::move_assignment++; return *this; }
|
||||
~MovableCopyable() { if (debug) cout << "~MovableCopyable()" << " " << this << endl; Counter::destructor++; }
|
||||
|
||||
static void movein(MovableCopyable &&mcin) {
|
||||
MovableCopyable mc = std::move(mcin);
|
||||
}
|
||||
|
||||
static bool is_nullptr(MovableCopyable *p) {
|
||||
return p == nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
%}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
import cpp11_rvalue_reference_move_input.*;
|
||||
|
||||
public class cpp11_rvalue_reference_move_input_runme {
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("cpp11_rvalue_reference_move_input");
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
|
||||
{
|
||||
Counter.reset_counts();
|
||||
MovableCopyable mo = new MovableCopyable(222);
|
||||
Counter.check_counts(1, 0, 0, 0, 0, 0);
|
||||
MovableCopyable.movein(mo);
|
||||
Counter.check_counts(1, 0, 0, 1, 0, 2);
|
||||
if (!MovableCopyable.is_nullptr(mo))
|
||||
throw new RuntimeException("is_nullptr failed");
|
||||
mo.delete();
|
||||
Counter.check_counts(1, 0, 0, 1, 0, 2);
|
||||
}
|
||||
|
||||
{
|
||||
// Move constructor test
|
||||
Counter.reset_counts();
|
||||
MovableCopyable mo = new MovableCopyable(222);
|
||||
Counter.check_counts(1, 0, 0, 0, 0, 0);
|
||||
MovableCopyable mo_moved = new MovableCopyable(mo);
|
||||
Counter.check_counts(1, 0, 0, 1, 0, 1);
|
||||
if (!MovableCopyable.is_nullptr(mo))
|
||||
throw new RuntimeException("is_nullptr failed");
|
||||
mo.delete();
|
||||
Counter.check_counts(1, 0, 0, 1, 0, 1);
|
||||
mo_moved.delete();
|
||||
Counter.check_counts(1, 0, 0, 1, 0, 2);
|
||||
}
|
||||
|
||||
{
|
||||
// Move assignment operator test
|
||||
Counter.reset_counts();
|
||||
MovableCopyable mo111 = new MovableCopyable(111);
|
||||
MovableCopyable mo222 = new MovableCopyable(222);
|
||||
Counter.check_counts(2, 0, 0, 0, 0, 0);
|
||||
mo111.MoveAssign(mo222);
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
if (!MovableCopyable.is_nullptr(mo222))
|
||||
throw new RuntimeException("is_nullptr failed");
|
||||
mo222.delete();
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 1);
|
||||
mo111.delete();
|
||||
Counter.check_counts(2, 0, 0, 0, 1, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -192,10 +192,25 @@ try {
|
|||
}
|
||||
}
|
||||
%}
|
||||
%typemap(javarelease) SWIGTYPE %{
|
||||
|
||||
%typemap(javabody) SWIGTYPE %{
|
||||
private transient long swigCPtr;
|
||||
protected transient boolean swigCMemOwn;
|
||||
|
||||
protected $javaclassname(long cPtr, boolean cMemoryOwn) {
|
||||
swigCMemOwn = cMemoryOwn;
|
||||
swigCPtr = cPtr;
|
||||
}
|
||||
|
||||
protected static long getCPtr($javaclassname obj) {
|
||||
return (obj == null) ? 0 : obj.swigCPtr;
|
||||
}
|
||||
|
||||
protected static long swigRelease($javaclassname obj) {
|
||||
long ptr = 0;
|
||||
if (obj != null) {
|
||||
if (!obj.swigCMemOwn)
|
||||
throw new RuntimeException("Cannot release ownership as memory is not owned");
|
||||
ptr = obj.swigCPtr;
|
||||
obj.swigCMemOwn = false;
|
||||
try {
|
||||
|
|
@ -208,6 +223,7 @@ try {
|
|||
}
|
||||
%}
|
||||
|
||||
|
||||
%inline %{
|
||||
struct NoExceptTest {
|
||||
unsigned int noExceptionPlease() { return 123; }
|
||||
|
|
|
|||
|
|
@ -700,6 +700,7 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
|
|||
SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type reference is null");
|
||||
return $null;
|
||||
} %}
|
||||
%typemap(freearg) SWIGTYPE && %{ delete $1; %};
|
||||
%typemap(out) SWIGTYPE *
|
||||
%{ *($&1_ltype)&$result = $1; %}
|
||||
%typemap(out, fragment="SWIG_PackData", noblock=1) SWIGTYPE (CLASS::*) {
|
||||
|
|
@ -1101,7 +1102,8 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
|
|||
jobjectArray
|
||||
"$javainput"
|
||||
%typemap(javain) SWIGTYPE "$&javaclassname.getCPtr($javainput)"
|
||||
%typemap(javain) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] "$javaclassname.getCPtr($javainput)"
|
||||
%typemap(javain) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$javaclassname.getCPtr($javainput)"
|
||||
%typemap(javain) SWIGTYPE && "$javaclassname.swigRelease($javainput)"
|
||||
%typemap(javain) SWIGTYPE (CLASS::*) "$javaclassname.getCMemberPtr($javainput)"
|
||||
|
||||
/* The javaout typemap is used for converting function return types from the return type
|
||||
|
|
@ -1216,6 +1218,18 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
|
|||
CPTR_VISIBILITY static long getCPtr($javaclassname obj) {
|
||||
return (obj == null) ? 0 : obj.swigCPtr;
|
||||
}
|
||||
|
||||
CPTR_VISIBILITY static long swigRelease($javaclassname obj) {
|
||||
long ptr = 0;
|
||||
if (obj != null) {
|
||||
if (!obj.swigCMemOwn)
|
||||
throw new RuntimeException("Cannot release ownership as memory is not owned");
|
||||
ptr = obj.swigCPtr;
|
||||
obj.swigCMemOwn = false;
|
||||
obj.delete();
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
%}
|
||||
|
||||
// Derived proxy classes
|
||||
|
|
@ -1230,6 +1244,18 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
|
|||
CPTR_VISIBILITY static long getCPtr($javaclassname obj) {
|
||||
return (obj == null) ? 0 : obj.swigCPtr;
|
||||
}
|
||||
|
||||
CPTR_VISIBILITY static long swigRelease($javaclassname obj) {
|
||||
long ptr = 0;
|
||||
if (obj != null) {
|
||||
if (!obj.swigCMemOwn)
|
||||
throw new RuntimeException("Cannot release ownership as memory is not owned");
|
||||
ptr = obj.swigCPtr;
|
||||
obj.swigCMemOwn = false;
|
||||
obj.delete();
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
%}
|
||||
%enddef
|
||||
|
||||
|
|
@ -1249,6 +1275,10 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
|
|||
CPTR_VISIBILITY static long getCPtr($javaclassname obj) {
|
||||
return (obj == null) ? 0 : obj.swigCPtr;
|
||||
}
|
||||
|
||||
CPTR_VISIBILITY static long swigRelease($javaclassname obj) {
|
||||
return (obj == null) ? 0 : obj.swigCPtr;
|
||||
}
|
||||
%}
|
||||
|
||||
%typemap(javabody) TYPE (CLASS::*) %{
|
||||
|
|
|
|||
|
|
@ -30,20 +30,6 @@
|
|||
return (cPtr == 0) ? null : new $typemap(jstype, TYPE)(cPtr, true);
|
||||
}
|
||||
|
||||
%typemap(javarelease) TYPE %{
|
||||
protected static long swigRelease($javaclassname obj) {
|
||||
long ptr = 0;
|
||||
if (obj != null) {
|
||||
if (!obj.swigCMemOwn)
|
||||
throw new RuntimeException("Cannot release ownership as memory is not owned");
|
||||
ptr = obj.swigCPtr;
|
||||
obj.swigCMemOwn = false;
|
||||
obj.delete();
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
%}
|
||||
|
||||
%template() std::unique_ptr< TYPE >;
|
||||
%enddef
|
||||
|
||||
|
|
|
|||
|
|
@ -2025,8 +2025,6 @@ public:
|
|||
typemapLookup(n, "javabody", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class
|
||||
NIL);
|
||||
|
||||
Printv(proxy_class_def, typemapLookup(n, "javarelease", typemap_lookup_type, WARN_NONE), NIL);
|
||||
|
||||
// C++ destructor is wrapped by the delete method
|
||||
// Note that the method name is specified in a typemap attribute called methodname
|
||||
String *destruct = NewString("");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue