swig/SWIG/CHANGES.current
Marcelo Matus b67a93a3d6 CHANGES.current
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@7861 626c5289-ae23-0410-ae9c-e8d60b6d4f22
2005-11-21 21:31:21 +00:00

699 lines
22 KiB
Text

Version 1.3.28 (unreleased).
===========================
11/21/2005: mmatus
[ruby + python]
Fixes for directors + pointers, ugly problem with not easy
solution. Before we identified this case as problematic:
virtual const MyClass& my_method();
but it turns out that all the cases where a pointer, array or
reference is returned, are problematic, even for
primitive types (as int, double, char*, etc).
To try to fix the issue, a new typemap was added,
'directorfree', which is used to 'free' the resources
allocated during the 'directorout' phase. At the same
time, a primitive garbage collector engine was added to
deal with orphans addresses, when needed.
The situation now is much better, but still you can have
memory exaustation if recursion is used.
So, still you need to avoid returning pointers, arrays or
references when using director methods.
- Added stdint.i
11/14/2005: wsfulton
More types added to windows.i, eg UINT8, WORD, BYTE etc.
Including windows.i will also enable SWIG to parse the __declspec Microsoft
extension, eg __declspec(dllimport). Also other Windows calling conventions
such as __stdcall.
11/10/2005: wsfulton
New library file for Windows - windows.i. This file will contain useful type
information for users who include windows.h. Initial support is for the
non ISO integral types: __int8, __int16, __int32, __int64 and unsigned versions.
The unsigned versions previously could not be parsed by SWIG. SF #872013.
11/09/2005: wsfulton
[Java, C#] Portability warning for files which will overwrite each other on case
insensitive file systems such as FAT32/NTFS. This will occur, for example, when two
class names are the same barring case. The warning is issued on all platforms and
can be suppressed with the usual warning suppression techniques. SF bug #1084507.
11/09/2005: wsfulton
./configure --with-python --with-ruby --with-perl5 etc enable these languages,
ie the --with-xxxx options, where no path is specified, work the same as if
the option was not specified at all. Based on patches #1335042 #1329048 #1329047.
11/09/2005: dancy
[Allegrocl]
Add C++ support to the Allegrocl module. Further
enhances the C support as well. Some of the
features:
- MUCH better generation of foreign types based on
the C/C++ types for use in defining the FFI on
the lisp side. We don't pass everything as a (* :void)
any longer.
- Uses typemaps for better control of type conversions
and code generation in the generated lisp and c++ wrapper
code.
- CLOS wrapping of pointers returned from foreign space
makes it easier to differentiate pointers in user code.
The wrapping objects can be passed directly to FF calls.
- Defun wrapping of FF calls, allowing for more lispy
interface. Conversion, GCing, of lisp objects to
foreign objects can be done in the wrapping defun via
the use of typemaps.
- overload dispatching implemented on the lisp side
using generic functions.
- Templates and synonymous types supported.
11/07/2005: mmatus
[Python] Adding proper support for multi-inheritance in
the python side, ie, if you have two C++ wrapped class, Foo
and Bar, now:
class MyPythonClass(Foo,Bar):
....
will properly work, even with directors, and the
deallocation of Foo.this and Bar.this will follow
correctly. Before, since a class can only have one 'this'
instance (not as in C++), only the last base class was
properly deletted, or detected with directors.
Now 'self.this' can be a list, which will contain the C++
instance pointers for all the base classes.
Also, swig.this is responsible for deallocating the C++
instance(s), and the __del__ method is not emitted unless
the user preppend/append some code to it.
- Swig now can detect memory leaks, ie, if you still
use the non-shadow module, and type something like
import _example
f = _example.new_Foo()
and forgot to call _example.delete_Foo(f), then swig will
tell you that there is a memory leak.
Otherwise, if you always use the shadow module, probably
you will never ever see this warning unless there is
something wrong inside the swig wrapping code.
*** POTENTIAL INCOMPATIBILITY ***
If you overloaded the __del__ method, and call the base
one without a try block, as in
class MyClass(SwigClass):
def __del__(self):
<your code here>
SwigClass.__del__(self)
python could complain that the method SwigClass.__del__ is
undefined. Try to use instead:
def __del__(self):
<your code here>
try: SwigClass.__del__(self)
except: pass
or simply
def __del__(self):
<your code here>
11/02/2005: mmatus
[Python] Adding more fun to STL/STD containers, now you
can do
%template(pyset) std::set<PyObject *>;
%template(pyvector) std::vector<PyObject *>;
%template() std::pair<PyObject *,PyObject *>;
%template(pyvector) std::map<PyObject *,PyObject *>;
....
The same applies to std::list, std::deque, std::multiset, etc.
Then, at the python side you can do now:
# C++ std::vector as native python sequence
v = pyvector([1,"hello",(1,2)])
print v[1]
>> 'hello'
print v[2]
>> (1,2)
# C++ std::set as native python sequence
s = pyset()
s.insert((1,2))
s.insert(1)
s.insert("hello")
sum=()
for i in s:
sum +=(i,)
print sum
>>> (1, 'hello', (1, 2))
# C++ std::map as native python sequence
m = pymap()
m["foo"] = "hello"
m[1] = (1,2)
pm = {}
for k in m:
pm[k] = m[k]
print pm
>>> {1: (1, 2), 'foo': 'hello'}
ie, the STD/STL containers work as real native python
container, with arbitrary item types and so.
But since normal C++ containers do not properly ref/unref
their items, you should use the safer versions:
%template(pyset) std::set<swig::PyObject_ptr>;
%template(pyvector) std::vector<swig::PyObject_ptr>;
%template() std::pair<swig::PyObject_ptr, swig::PyObject_ptr>;
%template(pyvector) std::map<swig::PyObject_ptr,swig::PyObject_ptr>;
....
where swig::PyObject_ptr is a PyObject * envelope class provided
to safely incref/decref the python object.
So, now you can use all the STL/STD containers as native
Python containers.
Note 1: std::map, std::set and the other 'ordered'
containers will properly use PyObject_Compare for sorting,
when needed.
Note 2: all the STL/STD containers have a limit size of
SIZE_MAX, ie, you can have manage containers larger than
INT_MAX, the python limit.
11/02/2005: mmatus
[Python]
- add 'iterator()' method for all sequences and additionally
'key_iterator()' for maps.
'iterator()' will always return the native C++ iterator.
Additionally, in maps, 'key_iterator()' will return a python
iterator using only the map keys.
In general the sequence method __iter__ will call
'iterator()', returning the native C++ iterator, but in
maps it will call 'key_iterator()', maintaining
backward compatibility.
Hence, for std::maps, you can play then with the native
C++ iterator, which value is a (key, value) pair, by
calling map.iterator(), as with map.begin(), map.end(), etc.
The difference is that map.iterator() returns a safe
'close' iterator, while map.begin() and map.end() are
'open' iterators.
A 'close' iterator knows the begin and the end of the
sequence, and it never can seg. fault. A 'open'
iterator, as in C++, can seg. fault at the C++ side.
# a close iterator is safe in the following example.
# the next() method will throw a StopIteration
# exception as needed
i = seq.iterator()
try:
while True:
sum += i.next()
except: pass
# an open iterator always need to be checked,
# or it will crash at the C++ side
current = seq.begin()
end = seq.end()
while (current != end):
sum += current.next()
[Python]
- Finally, when we call
f = Foo()
the construction is 'one-way'. Before construction was done
something like
Foo() (python) -> _new_Foo() (C++)
new_Foo() (C++) -> FooPtr() (python)
FooPtr() (python) -> Foo() (python)
and returning a pointer was done like
NewPointerObj() (C++) -> FooPtr() (python)
FooPtr(python) -> Foo() (python)
ie, we when going back and forward between the C++ and
python side.
Now since there is no FooPtr the construction process is
Foo() (python) -> _new_Foo() (C++)
_new_Foo() (C++) -> NewPointerObj() (C++) (no shadow class)
and returning a pointer is done
NewPointerObj() (C++) (with shadow class) -> NewInstaceObj() (C++)
where NewInstanceObj creates a new instance without
calling __init__ and it doesn't go 'back' to python, is
'pure' C API.
- With this change, and the other ones in the
PySwigObject type, which now carries the thisown and
swig_type_info pointer, the generated code should be as
fast as boost::Python and/or the other python wrappers
based in pure Python/C API calls.
As a reference, the profiletest_runme.py example, which
does a simple call function many times, such as this code:
import profiletest
a = profiletest.A()
b = profiletest.B()
for i in range(0,1000000)
a = b.fn(a)
where fn is defined as 'A* B::fn(A *a) {return a;}',
produces the following times
nomodern modern
swig-1.3.26 19.70s 5.98s
swig-CVS 0.99s 0.98s
Clearly, there is a large improvement for the python
'nomodern' mode. Still, the 'modern' mode is around
6 times faster than before. For the same test, but
using the non-shadow version of the module, we get
_profiletest (non-shadow)
swig-1.3.26 0.80s
swig-CVS 0.60s
Hence, now for practical porpuses, the proxy overhead
is insignificant.
Note that the performance numbers we are showing is for
a simple module (two types) and a simple function (one
argument). For real situations, with modules with many
more types and/or functions with many more parameters,
you will see even better results.
10/31/2005: mmatus
[Python]
- Finally, no more ClassPtr shadow classes. You will see
only a clean Class shadow class in the .py file.
- No more thisown attribute either, the PySwigObject now
carries the ownership info.
You can also do something like
print self.this.own()
>>> True
self.this.disown()
print self.this.own()
>>> False
self.this.acquire()
print self.this.own()
>>> True
- Support for iterators in STL/STD containers, for example, if you have
%template<set_string> std::set<std::string>;
you can use the C++ iterators as:
s = set_string()
s.append("c")
s.append("a")
s.append("b")
b = s.begin()
e = s.end()
sum = ""
while (b != e):
sum += b.next()
print sum
>>> "abc"
advance the iterator as in C++
current = s.begin()
current += 1
print current.value()
>>> "b"
now using the reverse operators
b = s.rbegin()
e = s.rend()
sum = ""
while (b != e):
sum += b.next()
print sum
>>> "cba"
or the 'previous' method
b = s.begin()
e = s.end()
sum = ""
while (b != e):
sum += e.previous()
print sum
>>> "cba"
or just as in a python fashion
for i in s:
sum += i
Note 1: Iterators in C++ are very powerful, but
dangerous too. And in python you can shoot your foot
as well as in C++, so, be careful.
Note 2: the iterators are 'light', ie, they do not
convert sequence elements until you request so, via
next(), value() or previous(). If you just increment/decrement one
no conversion is performed, for example:
b = s.begin()
b += 1
b.incr()
b.incr(2)
b.decr(2)
b.decr()
b -= 1
only the iterator is modified, and not value wrapper
is generated. Other typical C++ operations are also
available, such as:
print s.end() - s.begin()
>>> 3
f = s.begin() + 1
print f.value()
>>> "b"
l = s.end() - 1
print l.value()
>>> "c"
etc. Of course, the 'find', 'insert', 'erase', and
so on methods also supports iterators now, ie:
i = s.begin()
i += 1
s.erase(i)
for i in s:
sum += i
print sum
>>> "ac"
*** POTENTIAL INCOMPATIBILITY ***
There is no more 'thisown' attribute. If you use it, you
need to change as follows:
if (self.thisown): ==> if (self.this.own()):
self.thisown = 1 ==> self.this.acquire()
self.thisown = 0 ==> self.this.disown()
if you really really like the old 'thisown' attribute, you
can submit a patch to treat it as a property, and dispatch
the new method calls. Of course, before you try, it needs
to work with old and new python versions, and with classic
and modern python classes.
10/30/2005: mkoeppe
[Guile] Make declared and defined linkage of SWIG_init consistent.
Reported by Steven G. Johnson (SF patch 1315498).
10/26/2005: mmatus
- Added the attribute.i file to the global library director.
Now it can be used from other languages that do not use
the unified typemap library as well.
So, if you have something like:
%include attribute.i
%attribute(A, int, a, get_a, set_a);
struct A
{
int get_a() const;
void set_a(int aa);
};
%attribute_ref(B, int, c);
struct B
{
int& c();
};
then in the target language the 'A.a' and 'B.c' attributes will
be visible, ie, you can access them as plain variables:
f = A()
f.a = 3
g = B()
g.c = 3
h = f.a + g.c
and the proper get/set methods will be dispatched. See
attribute.i for more info.
- More cleanups around and adding more test-cases. The
DISOWN typemap now is tested and working in all the
languages that use the unified typemap library, ie, tcl,
ruby, perl and python.
10/25/2005: mmatus
- Perl, complete the DISOWN typemap.
- added the attribute.i file to the unified typemap
library (before was only usable from python).
- uniform the names for the setter and getter methods in
perl,tcl,ruby and python, so, the attribute.i library
can work across them.
- see the li_attribute.i test-case or the library file
Lib/typemaps/attribute.swg
for more info about how to use it.
10/24/2005: mmatus
- Perl uses now the unified typemap library.
- Changes in ruby to use the $track option in typemaps.
- Changes in the unified typemap library to follow the
convention that all macros that are not used in the
C/C++ side starts with %, such as
%delete
%new_array
etc.
- Documenting fragments, see fragments.swg.
- Cleaner way to use the unified typemap library, include
just <typemaps/swigtypes.swg>.
Check some of the supported languages: perl, tcl, ruby,
python.
Always start with the head file, such as
python/python.swg
tcl/tcl8.swg
ruby/ruby.swg
perl5/perl5.swg
and the principal file that invokes the unified library, such as
python/pytypemaps.swg
tcl/tcltypemaps.swg
ruby/rubytypemaps.swg
perl/perltypemaps.swg
The file that provide the specialization for each
language are the one that provides the basic types:
python/pyprimtypes.swg
ruby/rubyprimtypes.swg
tcl/tclprimtypes.swg
perl5/perlprimtypes.swg
and the string manipulation:
python/pystrings.swg
ruby/rubystrings.swg
tcl/tclstrings.swg
perl5/perlstrings.swg
The rest of the files, such as carray.i, are mostly one
line files that include the proper typemap library
version.
10/23/2005: wuzzeb
Chicken:
+ pointers to member functions finally work properly
+ add test of member function pointers to cpp_basic.i
10/20/2005: dancy
[allegrocl] Added C++ support. Large update, many changes. See
newly added Allegro Common Lisp section in lisp.html
10/20/2005: mmatus
Ruby, Tcl, Python:
- Uniform way to fail (label fail:), now finally
SWIG_exception works across the three languages and all
the typemaps.
- Add proper cleanup code to ruby
- More valgrind fixes
- Simplify the inline use, it seems a small interface of
20,000 lines (plus many many templates0 can break
gcc -O3 easily.
- Finalize the typemaps library. All the old *.i files
(carray.i, cpointer.i, exception.i) had been implemented
in the new typemaps library.
10/19/2005: wuzzeb
Update the Runtime Typemap documentation in Typemaps.html
10/18/2005: wuzzeb
Chicken:
- Correctly handle %ignored classes
- Correctly convert long, long long, unsigned long, etc
to chicken primitives. (Thanks to Felix Winkelmann)
- Using argout parameters when the return value was a
wrapped pointer caused a memory corruption. The chicken
garbage collector moved a pointer out from under us.
This is now fixed by running all the proxy creation
functions as continuations after the wrapper function
returns. As part of this, we no longer need the
chickenfastproxy flag on output typemaps.
- using -proxy and -nocollection together works now
Before, it was not exporting the destructor in the proxy
wrapper.
10/18/2005: mmatus
Unifying the typemaps for
python, ruby, tcl
and in the process, fix several problems in three
languages to work in the "canonical" way now stablished in
the typemap library
SWIG/Lib/typempas
The current status of the unification is that everything
compiles and runs inside the test-suite and examples
directories. And for the first type we have three
languages than pass the primitive_types.i case.
Also, we have uniform way to treat the errors, for example
if you do something like
>>> from primitive_types import *
>>> print val_uchar(10)
10
>>> print val_uchar(1000)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
OverflowError: in argument 1 of type 'unsigned char'
you get the same exception in all the three languages.
And well, many more good things will come from this
unification, as proper support of the STL/STD classes
for all the languages, and hopefully, we can keep
adding other languages.
The hardest part, writting a common typemap library
that suites the three different languages, is done,
and adding another language it is easy now.
Still the global unification is not complete, the STL/STD
part is next, and probably adding one or two more
languages.
If you are curious, look at the python, ruby and/or tcl
directories to see what is needed to support the new
common typemaps library. Still, the final way to
integrate a new language could change as we move to
integrate the STD/STL.
*** POTENTIAL INCOMPATIBILITY ***
Some missing typemaps could start working, and change
the old expected behavior, specially in ruby and tcl.