Ensure the premature garbage collection prevention parameter (pgcpp) is generated for Java wrappers

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9943 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2007-09-19 23:17:50 +00:00
commit 7199cf2ef0
10 changed files with 156 additions and 18 deletions

View file

@ -1,5 +1,10 @@
Version 1.3.32 (in progress)
============================
19/07/2007: wsfulton
[Java] Ensure the premature garbage collection prevention parameter (pgcpp) is generated
where a parameter is passed by pointer reference, eg in the std::vector wrappers. The pgcpp
is also generated now when user's custom typemaps use a proxy class in the jstype typemap
and a 'long' in the jtype typemap.
09/18/2007: olly
[php] Add typemaps for handling parameters of type std::string &

View file

@ -24,6 +24,7 @@ CPP_TEST_CASES = \
java_lib_arrays_dimensionless \
java_lib_various \
java_jnitypes \
java_pgcpp \
java_pragmas \
java_prepost \
java_throws \

View file

@ -0,0 +1,30 @@
import java_pgcpp.*;
public class java_pgcpp_runme {
static {
try {
System.loadLibrary("java_pgcpp");
} 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[]) {
Classic object = new Classic();
long ptr = object.getCPtrValue();
java_pgcppJNI.new_Classic__SWIG_1(ptr, object, ptr, object, ptr, object, ptr, object, ptr, object);
java_pgcppJNI.new_Classic__SWIG_2(ptr, object, ptr, object, ptr, object, ptr, object, ptr, object, false);
java_pgcppJNI.Classic_method(ptr, object, ptr, object, ptr, object, ptr, object, ptr, object, ptr, object);
java_pgcppJNI.Classic_methodconst(ptr, object, ptr, object, ptr, object, ptr, object, ptr, object, ptr, object);
java_pgcppJNI.function(ptr, object, ptr, object, ptr, object, ptr, object, ptr, object);
java_pgcppJNI.functionconst(ptr, object, ptr, object, ptr, object, ptr, object, ptr, object);
}
}

View file

@ -0,0 +1,36 @@
// Test the premature garbage collection prevention parameter (pgcpp) for the different ways of passing objects
%module java_pgcpp
%pragma(java) jniclassclassmodifiers="public class"
%typemap(javacode) Space::Classic %{
public long getCPtrValue() {
return this.swigCPtr;
}
%}
// Default pointer to pointer typemaps do not use proxy class, so make sure that the pgcpp is generated for these typemaps
%typemap(jni) Space::Classic ** "jlong"
%typemap(jtype) Space::Classic ** "long"
%typemap(jstype) Space::Classic ** " Classic "
%typemap(javain) Space::Classic ** "Classic.getCPtr($javainput)"
// Default typemaps for pass by value, ref, pointer and pointer reference should use pgcpp
%inline %{
namespace Space {
struct Classic {
Classic() {}
Classic(Classic c1, Classic& c2, Classic* c3, Classic*& c4, Classic** c5) {}
Classic(const Classic c1, const Classic& c2, const Classic* c3, const Classic*& c4, const Classic** c5, bool b) {}
void method(Classic c1, Classic& c2, Classic* c3, Classic*& c4, Classic** c5) {}
void methodconst(const Classic c1, const Classic& c2, const Classic* c3, const Classic*& c4, const Classic** c5) {}
};
void function(Classic c1, Classic& c2, Classic* c3, Classic*& c4, Classic** c5) {}
void functionconst(const Classic c1, const Classic& c2, const Classic* c3, const Classic*& c4, const Classic** c5) {}
}
%}

View file

@ -800,6 +800,7 @@ public:
/* Attach the non-standard typemaps to the parameter list. */
Swig_typemap_attach_parms("jni", l, f);
Swig_typemap_attach_parms("jtype", l, f);
Swig_typemap_attach_parms("jstype", l, f);
/* Get return types */
if ((tm = Swig_typemap_lookup_new("jni", n, "", 0))) {
@ -892,6 +893,12 @@ public:
// Premature garbage collection prevention parameter
if (!is_destructor) {
String *pgc_parameter = prematureGarbageCollectionPreventionParameter(pt, p);
/*
if (!pgc_parameter) {
Printf(stdout, "prematuregcp %s %s [%s]\n", symname, Getattr(n, "sym:overname"), pt);
Swig_print_node(p);
}
*/
if (pgc_parameter) {
Printf(imclass_class_code, ", %s %s_", pgc_parameter, arg);
Printf(f->def, ", jobject %s_", arg);
@ -1943,6 +1950,7 @@ public:
SwigType_add_pointer(this_type);
Parm *this_parm = NewParm(this_type, name);
Swig_typemap_attach_parms("jtype", this_parm, NULL);
Swig_typemap_attach_parms("jstype", this_parm, NULL);
if (prematureGarbageCollectionPreventionParameter(this_type, this_parm))
Printf(imcall, ", this");
@ -2916,16 +2924,50 @@ public:
* ----------------------------------------------------------------------------- */
String *prematureGarbageCollectionPreventionParameter(SwigType *t, Parm *p) {
String *jtype = Getattr(p, "tmap:jtype");
String *proxyClassName = 0;
String *jtype = NewString(Getattr(p, "tmap:jtype"));
// TODO: remove any C comments from jtype
// remove whitespace
Replaceall(jtype, " ", "");
Replaceall(jtype, "\t", "");
if (Cmp(jtype, "long") == 0) {
if (proxy_flag) {
Node *n = classLookup(t);
if (n && !GetFlag(p, "tmap:jtype:nopgcpp") && !nopgcpp_flag) {
return Getattr(n, "sym:name");
if (!GetFlag(p, "tmap:jtype:nopgcpp") && !nopgcpp_flag) {
Node *n = classLookup(t);
if (n) {
// Found a struct/class parameter passed by value, reference, pointer, or pointer reference
proxyClassName = Getattr(n, "sym:name");
} else {
// Look for proxy class parameters passed to C++ layer using non-default typemaps, ie not one of above types
String *jstype = NewString(Getattr(p, "tmap:jstype"));
if (jstype) {
Hash *classes = getClassHash();
if (classes) {
// TODO: remove any C comments from jstype
// remove whitespace
Replaceall(jstype, " ", "");
Replaceall(jstype, "\t", "");
Iterator ki;
for (ki = First(classes); ki.key; ki = Next(ki)) {
Node *cls = ki.item;
if (cls && !Getattr(cls, "feature:ignore")) {
String *symname = Getattr(cls, "sym:name");
if (symname && Strcmp(symname, jstype) == 0) {
proxyClassName = symname;
}
}
}
}
}
Delete(jstype);
}
}
}
}
return NULL;
Delete(jtype);
return proxyClassName;
}
/*----------------------------------------------------------------------

View file

@ -2932,12 +2932,14 @@ Node *Language::classLookup(SwigType *s) {
n = Getattr(classtypes, s);
if (!n) {
Symtab *stab = 0;
SwigType *lt = SwigType_ltype(s);
SwigType *ty1 = SwigType_typedef_resolve_all(lt);
// SwigType *lt = SwigType_ltype(s);
// SwigType *ty1 = SwigType_typedef_resolve_all(lt);
SwigType *ty1 = SwigType_typedef_resolve_all(s);
SwigType *ty2 = SwigType_strip_qualifiers(ty1);
Delete(lt);
// Printf(stdout, " stages... ty1: %s ty2: %s\n", ty1, ty2);
// Delete(lt);
Delete(ty1);
lt = 0;
// lt = 0;
ty1 = 0;
String *base = SwigType_base(ty2);
@ -2968,10 +2970,12 @@ Node *Language::classLookup(SwigType *s) {
}
if (n) {
/* Found a match. Look at the prefix. We only allow
a few cases: pointers, references, and simple */
if ((Len(prefix) == 0) || /* Simple type */
(Strcmp(prefix, "p.") == 0) || /* pointer */
(Strcmp(prefix, "r.") == 0)) { /* reference */
the cases where where we want a proxy class for the particular type */
if ((Len(prefix) == 0) || // simple type (pass by value)
(Strcmp(prefix, "p.") == 0) || // pointer
(Strcmp(prefix, "r.") == 0) || // reference
(Strcmp(prefix, "r.p.") == 0) || // pointer by reference
SwigType_prefix_is_simple_1D_array(prefix)) { // Simple 1D array (not arrays of pointers/references)
SwigType *cs = Copy(s);
Setattr(classtypes, cs, n);
Delete(cs);
@ -3356,3 +3360,7 @@ String *Language::runtimeCode() {
String *Language::defaultExternalRuntimeFilename() {
return 0;
}
Hash *Language::getClassHash() const {
return classhash;
}

View file

@ -259,6 +259,9 @@ protected:
/* Return the real name of the current class */
String *getClassName() const;
/* Return the classes hash */
Hash *getClassHash() const;
/* Return the current class prefix */
String *getClassPrefix() const;

View file

@ -168,12 +168,7 @@ void SwigType_push(SwigType *t, String *cons) {
}
/* -----------------------------------------------------------------------------
* SwigType_ispointer()
* SwigType_ispointer_return()
* SwigType_isarray()
* SwigType_isreference()
* SwigType_isfunction()
* SwigType_isqualifier()
*
* Testing functions for querying a raw datatype
* ----------------------------------------------------------------------------- */

View file

@ -140,6 +140,7 @@ extern "C" {
extern int SwigType_isreference(SwigType *t);
extern int SwigType_isreference_return(SwigType *t);
extern int SwigType_isarray(SwigType *t);
extern int SwigType_prefix_is_simple_1D_array(SwigType *t);
extern int SwigType_isfunction(SwigType *t);
extern int SwigType_isqualifier(SwigType *t);
extern int SwigType_isconst(SwigType *t);

View file

@ -556,6 +556,23 @@ int SwigType_isarray(SwigType *t) {
}
return 0;
}
/*
* SwigType_prefix_is_simple_1D_array
*
* Determine if the type is a 1D array type that is treated as a pointer within SWIG
* eg Foo[], Foo[3] return true, but Foo[3][3], Foo*[], Foo*[3], Foo**[] return false
*/
int SwigType_prefix_is_simple_1D_array(SwigType *t) {
char *c = Char(t);
if (c && (strncmp(c, "a(", 2) == 0)) {
c = strchr(c, '.');
c++;
return (*c == 0);
}
return 0;
}
/* Remove all arrays */
SwigType *SwigType_pop_arrays(SwigType *t) {