Made hash store a counter to the ruby VALUE object.
This should avoid a potential subtle bug when using operator=. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9829 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
5aaf3003b6
commit
776398cd1d
1 changed files with 22 additions and 10 deletions
|
|
@ -136,10 +136,8 @@ namespace swig {
|
|||
rb_gc_unregister_address( &_hash );
|
||||
}
|
||||
|
||||
|
||||
GC_VALUE() :_obj( Qnil )
|
||||
GC_VALUE() : _obj( Qnil )
|
||||
{
|
||||
GC_register();
|
||||
}
|
||||
|
||||
GC_VALUE(const GC_VALUE& item) : _obj(item._obj)
|
||||
|
|
@ -159,23 +157,37 @@ namespace swig {
|
|||
|
||||
GC_VALUE & operator=(const GC_VALUE& item)
|
||||
{
|
||||
GC_unregister();
|
||||
_obj = item._obj;
|
||||
return *this;
|
||||
GC_register();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void GC_register()
|
||||
{
|
||||
if ( FIXNUM_P(_obj) || SPECIAL_CONST_P(_obj) || SYMBOL_P(_obj) ) return;
|
||||
rb_hash_aset( _hash, _obj, Qtrue );
|
||||
if ( FIXNUM_P(_obj) || SPECIAL_CONST_P(_obj) || SYMBOL_P(_obj) )
|
||||
return;
|
||||
VALUE val = rb_hash_aref( _hash, _obj );
|
||||
unsigned n = FIXNUM_P(val) ? NUM2UINT(val) : 0;
|
||||
++n;
|
||||
rb_hash_aset( _hash, _obj, INT2NUM(n) );
|
||||
}
|
||||
|
||||
void GC_unregister()
|
||||
{
|
||||
if ( FIXNUM_P(_obj) || SPECIAL_CONST_P(_obj) || SYMBOL_P(_obj) ) return;
|
||||
if ( FIXNUM_P(_obj) || SPECIAL_CONST_P(_obj) || SYMBOL_P(_obj) )
|
||||
return;
|
||||
// this test should not be needed but I've noticed some very erratic
|
||||
// behavior of none being unregistered in some very rare situations.
|
||||
if ( BUILTIN_TYPE(_obj) == T_NONE ) return;
|
||||
rb_hash_delete( _hash, _obj );
|
||||
|
||||
VALUE val = rb_hash_aref( _hash, _obj );
|
||||
unsigned n = FIXNUM_P(val) ? NUM2UINT(val) : 1;
|
||||
--n;
|
||||
if ( n )
|
||||
rb_hash_aset( _hash, _obj, INT2NUM(n) );
|
||||
else
|
||||
rb_hash_delete( _hash, _obj );
|
||||
}
|
||||
|
||||
operator VALUE() const
|
||||
|
|
@ -214,8 +226,8 @@ namespace swig {
|
|||
args.id = op_id; \
|
||||
args.nargs = 1; \
|
||||
args.target = VALUE(other); \
|
||||
ret = rb_protect( PROTECTFUNC(swig_protect_funcall), VALUE(&args), \
|
||||
&status ); \
|
||||
ret = rb_protect( PROTECTFUNC(swig_protect_funcall), \
|
||||
VALUE(&args), &status ); \
|
||||
} \
|
||||
if ( ret == Qnil ) { \
|
||||
VALUE a = rb_funcall( _obj, hash_id, 0 ); \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue