Fix Ruby tracking code (BZ#1225140)
This commit is contained in:
parent
2fa3b57593
commit
0c140872c0
28
swig.spec
28
swig.spec
@ -5,13 +5,6 @@
|
||||
%{!?guile:%global guile 1}
|
||||
%{!?lualang:%global lualang 1}
|
||||
|
||||
# Ruby segfaults in some tests on fc23 and only on armv7-arch.
|
||||
#%%ifarch %%{arm} s390
|
||||
# Disable Ruby tests for all arches due to BZ#1225140
|
||||
%if 0%{?fedora} >= 23
|
||||
%{!?rubylang:%global rubylang 0}
|
||||
%endif # 0%%{?fedora} >= 23
|
||||
#%%endif #arch %%{arm} s390
|
||||
%{!?rubylang:%global rubylang 1}
|
||||
|
||||
%ifarch aarch64 %{arm} ppc64le ppc %{power64} s390 s390x
|
||||
@ -40,7 +33,7 @@
|
||||
Summary: Connects C/C++/Objective C to some high-level programming languages
|
||||
Name: swig
|
||||
Version: 3.0.7
|
||||
Release: 5%{?dist}
|
||||
Release: 6%{?dist}
|
||||
License: GPLv3+ and BSD
|
||||
URL: http://swig.sourceforge.net/
|
||||
Source0: http://downloads.sourceforge.net/project/swig/swig/swig-%{version}/swig-%{version}.tar.gz
|
||||
@ -48,6 +41,11 @@ Source0: http://downloads.sourceforge.net/project/swig/swig/swig-%{version}/swig
|
||||
Source1: description.h2m
|
||||
Patch1: swig207-setools.patch
|
||||
|
||||
# Ruby patches will be part of SWIG 3.0.8
|
||||
Patch2: swig307-Fix-Ruby-trackings-code-to-use-C-hash.patch
|
||||
Patch3: swig307-Ruby-trackings-patch-tidy-up.patch
|
||||
Patch4: swig307-Ruby-trackings-support-for-1.8.patch
|
||||
|
||||
BuildRequires: perl, python2-devel, pcre-devel
|
||||
BuildRequires: autoconf, automake, gawk, dos2unix
|
||||
BuildRequires: gcc-c++
|
||||
@ -111,6 +109,9 @@ This package contains documentation for SWIG and useful examples
|
||||
%setup -q -n swig-%{version}
|
||||
|
||||
%patch1 -p1 -b .setools
|
||||
%patch2 -p1 -b .rubyhash
|
||||
%patch3 -p1 -b .rubytidyup
|
||||
%patch4 -p1 -b .ruby18
|
||||
|
||||
for all in CHANGES README; do
|
||||
iconv -f ISO88591 -t UTF8 < $all > $all.new
|
||||
@ -201,13 +202,18 @@ ln -fs ../../bin/ccache-swig %{buildroot}%{_libdir}/ccache/swig
|
||||
%{_libdir}/ccache
|
||||
%{_mandir}/man1/ccache-swig.1*
|
||||
%{_mandir}/man1/swig.1*
|
||||
%doc ANNOUNCE CHANGES CHANGES.current LICENSE LICENSE-GPL
|
||||
%doc LICENSE-UNIVERSITIES COPYRIGHT README TODO
|
||||
%license LICENSE LICENSE-GPL LICENSE-UNIVERSITIES
|
||||
%doc ANNOUNCE CHANGES CHANGES.current
|
||||
%doc COPYRIGHT README TODO
|
||||
|
||||
%files doc
|
||||
%doc Doc Examples LICENSE LICENSE-GPL LICENSE-UNIVERSITIES COPYRIGHT
|
||||
%license LICENSE LICENSE-GPL LICENSE-UNIVERSITIES
|
||||
%doc Doc Examples COPYRIGHT
|
||||
|
||||
%changelog
|
||||
* Mon Sep 14 2015 Jitka Plesnikova <jplesnik@redhat.com> - 3.0.7-6
|
||||
- Fix Ruby tracking code (BZ#1225140)
|
||||
|
||||
* Thu Sep 03 2015 Jonathan Wakely <jwakely@redhat.com> - 3.0.7-5
|
||||
- Rebuilt for Boost 1.59
|
||||
|
||||
|
202
swig307-Fix-Ruby-trackings-code-to-use-C-hash.patch
Normal file
202
swig307-Fix-Ruby-trackings-code-to-use-C-hash.patch
Normal file
@ -0,0 +1,202 @@
|
||||
From 0e725b5d9bd534964ae606852453df46d04037ee Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Klaus=20K=C3=A4mpf?= <kkaempf@suse.de>
|
||||
Date: Thu, 3 Jan 2013 11:56:25 +0100
|
||||
Subject: [PATCH] Fix Ruby tracking code to use C hash
|
||||
|
||||
This is a patch to resolve SF bug 2034216 (Github issue #225)
|
||||
The bug is that the tracking code uses a ruby hash and thus may
|
||||
allocate objects (Bignum) while running the GC. This was tolerated in
|
||||
1.8 but is invalid (raises an exception) in 1.9.
|
||||
The patch uses a C hash (also used by ruby) instead.
|
||||
---
|
||||
Lib/ruby/rubytracking.swg | 127 ++++++++++++++++++----------------------------
|
||||
1 file changed, 49 insertions(+), 78 deletions(-)
|
||||
|
||||
diff --git a/Lib/ruby/rubytracking.swg b/Lib/ruby/rubytracking.swg
|
||||
index 0a36f4a..d974228 100644
|
||||
--- a/Lib/ruby/rubytracking.swg
|
||||
+++ b/Lib/ruby/rubytracking.swg
|
||||
@@ -22,19 +22,19 @@ extern "C" {
|
||||
# error sizeof(void*) is not the same as long or long long
|
||||
#endif
|
||||
|
||||
-
|
||||
-/* Global Ruby hash table to store Trackings from C/C++
|
||||
+/* Global hash table to store Trackings from C/C++
|
||||
structs to Ruby Objects.
|
||||
*/
|
||||
-static VALUE swig_ruby_trackings = Qnil;
|
||||
+static st_table* swig_ruby_trackings = NULL;
|
||||
+
|
||||
+VALUE get_swig_trackings_count(ANYARGS) {
|
||||
+ return SWIG2NUM(swig_ruby_trackings->num_entries);
|
||||
+}
|
||||
|
||||
-/* Global variable that stores a reference to the ruby
|
||||
- hash table delete function. */
|
||||
-static ID swig_ruby_hash_delete;
|
||||
|
||||
-/* Setup a Ruby hash table to store Trackings */
|
||||
+/* Setup a hash table to store Trackings */
|
||||
SWIGRUNTIME void SWIG_RubyInitializeTrackings(void) {
|
||||
- /* Create a ruby hash table to store Trackings from C++
|
||||
+ /* Create a hash table to store Trackings from C++
|
||||
objects to Ruby objects. */
|
||||
|
||||
/* Try to see if some other .so has already created a
|
||||
@@ -43,87 +43,47 @@ SWIGRUNTIME void SWIG_RubyInitializeTrackings(void) {
|
||||
This is done to allow multiple DSOs to share the same
|
||||
tracking table.
|
||||
*/
|
||||
- ID trackings_id = rb_intern( "@__trackings__" );
|
||||
+ VALUE trackings_value = Qnil;
|
||||
+ /* change the variable name so that we can mix modules
|
||||
+ compiled with older SWIG's */
|
||||
+ ID trackings_id = rb_intern( "@__safetrackings__" );
|
||||
VALUE verbose = rb_gv_get("VERBOSE");
|
||||
rb_gv_set("VERBOSE", Qfalse);
|
||||
- swig_ruby_trackings = rb_ivar_get( _mSWIG, trackings_id );
|
||||
+ trackings_value = rb_ivar_get( _mSWIG, trackings_id );
|
||||
rb_gv_set("VERBOSE", verbose);
|
||||
|
||||
- /* No, it hasn't. Create one ourselves */
|
||||
- if ( swig_ruby_trackings == Qnil )
|
||||
- {
|
||||
- swig_ruby_trackings = rb_hash_new();
|
||||
- rb_ivar_set( _mSWIG, trackings_id, swig_ruby_trackings );
|
||||
- }
|
||||
-
|
||||
- /* Now store a reference to the hash table delete function
|
||||
- so that we only have to look it up once.*/
|
||||
- swig_ruby_hash_delete = rb_intern("delete");
|
||||
-}
|
||||
-
|
||||
-/* Get a Ruby number to reference a pointer */
|
||||
-SWIGRUNTIME VALUE SWIG_RubyPtrToReference(void* ptr) {
|
||||
- /* We cast the pointer to an unsigned long
|
||||
- and then store a reference to it using
|
||||
- a Ruby number object. */
|
||||
-
|
||||
- /* Convert the pointer to a Ruby number */
|
||||
- return SWIG2NUM(ptr);
|
||||
-}
|
||||
-
|
||||
-/* Get a Ruby number to reference an object */
|
||||
-SWIGRUNTIME VALUE SWIG_RubyObjectToReference(VALUE object) {
|
||||
- /* We cast the object to an unsigned long
|
||||
- and then store a reference to it using
|
||||
- a Ruby number object. */
|
||||
-
|
||||
- /* Convert the Object to a Ruby number */
|
||||
- return SWIG2NUM(object);
|
||||
-}
|
||||
-
|
||||
-/* Get a Ruby object from a previously stored reference */
|
||||
-SWIGRUNTIME VALUE SWIG_RubyReferenceToObject(VALUE reference) {
|
||||
- /* The provided Ruby number object is a reference
|
||||
- to the Ruby object we want.*/
|
||||
+ /* The trick here is that we have to store the hash table
|
||||
+ pointer in a Ruby variable. We do not want Ruby's GC to
|
||||
+ treat this pointer as a Ruby object, so we convert it to
|
||||
+ a Ruby numeric value. */
|
||||
+ if (trackings_value == Qnil) {
|
||||
+ /* No, it hasn't. Create one ourselves */
|
||||
+ swig_ruby_trackings = st_init_numtable();
|
||||
+ rb_ivar_set( _mSWIG, trackings_id, SWIG2NUM(swig_ruby_trackings) );
|
||||
+ }
|
||||
+ else {
|
||||
+ swig_ruby_trackings = (st_table*)NUM2SWIG(trackings_value);
|
||||
+ }
|
||||
|
||||
- /* Convert the Ruby number to a Ruby object */
|
||||
- return NUM2SWIG(reference);
|
||||
+ rb_define_virtual_variable("SWIG_TRACKINGS_COUNT", get_swig_trackings_count, NULL);
|
||||
}
|
||||
|
||||
/* Add a Tracking from a C/C++ struct to a Ruby object */
|
||||
SWIGRUNTIME void SWIG_RubyAddTracking(void* ptr, VALUE object) {
|
||||
- /* In a Ruby hash table we store the pointer and
|
||||
- the associated Ruby object. The trick here is
|
||||
- that we cannot store the Ruby object directly - if
|
||||
- we do then it cannot be garbage collected. So
|
||||
- instead we typecast it as a unsigned long and
|
||||
- convert it to a Ruby number object.*/
|
||||
-
|
||||
- /* Get a reference to the pointer as a Ruby number */
|
||||
- VALUE key = SWIG_RubyPtrToReference(ptr);
|
||||
-
|
||||
- /* Get a reference to the Ruby object as a Ruby number */
|
||||
- VALUE value = SWIG_RubyObjectToReference(object);
|
||||
-
|
||||
/* Store the mapping to the global hash table. */
|
||||
- rb_hash_aset(swig_ruby_trackings, key, value);
|
||||
+ st_insert(swig_ruby_trackings, (st_data_t)ptr, object);
|
||||
}
|
||||
|
||||
/* Get the Ruby object that owns the specified C/C++ struct */
|
||||
SWIGRUNTIME VALUE SWIG_RubyInstanceFor(void* ptr) {
|
||||
- /* Get a reference to the pointer as a Ruby number */
|
||||
- VALUE key = SWIG_RubyPtrToReference(ptr);
|
||||
-
|
||||
/* Now lookup the value stored in the global hash table */
|
||||
- VALUE value = rb_hash_aref(swig_ruby_trackings, key);
|
||||
-
|
||||
- if (value == Qnil) {
|
||||
- /* No object exists - return nil. */
|
||||
- return Qnil;
|
||||
+ VALUE value;
|
||||
+
|
||||
+ if (st_lookup(swig_ruby_trackings, (st_data_t)ptr, &value)) {
|
||||
+ return value;
|
||||
}
|
||||
else {
|
||||
- /* Convert this value to Ruby object */
|
||||
- return SWIG_RubyReferenceToObject(value);
|
||||
+ return Qnil;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,12 +92,8 @@ SWIGRUNTIME VALUE SWIG_RubyInstanceFor(void* ptr) {
|
||||
since the same memory address may be reused later to create
|
||||
a new object. */
|
||||
SWIGRUNTIME void SWIG_RubyRemoveTracking(void* ptr) {
|
||||
- /* Get a reference to the pointer as a Ruby number */
|
||||
- VALUE key = SWIG_RubyPtrToReference(ptr);
|
||||
-
|
||||
- /* Delete the object from the hash table by calling Ruby's
|
||||
- do this we need to call the Hash.delete method.*/
|
||||
- rb_funcall(swig_ruby_trackings, swig_ruby_hash_delete, 1, key);
|
||||
+ /* Delete the object from the hash table */
|
||||
+ st_delete(swig_ruby_trackings, (st_data_t *)&ptr, NULL);
|
||||
}
|
||||
|
||||
/* This is a helper method that unlinks a Ruby object from its
|
||||
@@ -147,10 +103,25 @@ SWIGRUNTIME void SWIG_RubyUnlinkObjects(void* ptr) {
|
||||
VALUE object = SWIG_RubyInstanceFor(ptr);
|
||||
|
||||
if (object != Qnil) {
|
||||
+ if (TYPE(object) != T_DATA)
|
||||
+ abort();
|
||||
DATA_PTR(object) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
+/* This is a helper method that iterates over all the trackings
|
||||
+ passing the C++ object pointer and its related Ruby object
|
||||
+ to the passed callback function. */
|
||||
+
|
||||
+/* Proxy method to abstract the internal trackings datatype */
|
||||
+static int _ruby_internal_iterate_callback(void* ptr, VALUE obj, void(*meth)(void* ptr, VALUE obj)) {
|
||||
+ (*meth)(ptr, obj);
|
||||
+ return ST_CONTINUE;
|
||||
+}
|
||||
+
|
||||
+SWIGRUNTIME void SWIG_RubyIterateTrackings( void(*meth)(void* ptr, VALUE obj) ) {
|
||||
+ st_foreach(swig_ruby_trackings, (int (*)(ANYARGS))&_ruby_internal_iterate_callback, (st_data_t)meth);
|
||||
+}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
--
|
||||
2.4.3
|
||||
|
76
swig307-Ruby-trackings-patch-tidy-up.patch
Normal file
76
swig307-Ruby-trackings-patch-tidy-up.patch
Normal file
@ -0,0 +1,76 @@
|
||||
From e14b392596f453dc8f437de90e8d405a04d5df62 Mon Sep 17 00:00:00 2001
|
||||
From: William S Fulton <wsf@fultondesigns.co.uk>
|
||||
Date: Sun, 13 Sep 2015 13:25:29 +0100
|
||||
Subject: [PATCH] Ruby trackings patch tidy up and add changes entry
|
||||
|
||||
Closes #225
|
||||
---
|
||||
Lib/ruby/rubytracking.swg | 16 +++++++---------
|
||||
1 file changed, 7 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/Lib/ruby/rubytracking.swg b/Lib/ruby/rubytracking.swg
|
||||
index d974228..37789c1 100644
|
||||
--- a/Lib/ruby/rubytracking.swg
|
||||
+++ b/Lib/ruby/rubytracking.swg
|
||||
@@ -27,7 +27,7 @@ extern "C" {
|
||||
*/
|
||||
static st_table* swig_ruby_trackings = NULL;
|
||||
|
||||
-VALUE get_swig_trackings_count(ANYARGS) {
|
||||
+static VALUE swig_ruby_trackings_count(ANYARGS) {
|
||||
return SWIG2NUM(swig_ruby_trackings->num_entries);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ SWIGRUNTIME void SWIG_RubyInitializeTrackings(void) {
|
||||
*/
|
||||
VALUE trackings_value = Qnil;
|
||||
/* change the variable name so that we can mix modules
|
||||
- compiled with older SWIG's */
|
||||
+ compiled with older SWIG's - this used to be called "@__trackings__" */
|
||||
ID trackings_id = rb_intern( "@__safetrackings__" );
|
||||
VALUE verbose = rb_gv_get("VERBOSE");
|
||||
rb_gv_set("VERBOSE", Qfalse);
|
||||
@@ -60,12 +60,11 @@ SWIGRUNTIME void SWIG_RubyInitializeTrackings(void) {
|
||||
/* No, it hasn't. Create one ourselves */
|
||||
swig_ruby_trackings = st_init_numtable();
|
||||
rb_ivar_set( _mSWIG, trackings_id, SWIG2NUM(swig_ruby_trackings) );
|
||||
- }
|
||||
- else {
|
||||
+ } else {
|
||||
swig_ruby_trackings = (st_table*)NUM2SWIG(trackings_value);
|
||||
}
|
||||
|
||||
- rb_define_virtual_variable("SWIG_TRACKINGS_COUNT", get_swig_trackings_count, NULL);
|
||||
+ rb_define_virtual_variable("SWIG_TRACKINGS_COUNT", swig_ruby_trackings_count, NULL);
|
||||
}
|
||||
|
||||
/* Add a Tracking from a C/C++ struct to a Ruby object */
|
||||
@@ -81,8 +80,7 @@ SWIGRUNTIME VALUE SWIG_RubyInstanceFor(void* ptr) {
|
||||
|
||||
if (st_lookup(swig_ruby_trackings, (st_data_t)ptr, &value)) {
|
||||
return value;
|
||||
- }
|
||||
- else {
|
||||
+ } else {
|
||||
return Qnil;
|
||||
}
|
||||
}
|
||||
@@ -114,13 +112,13 @@ SWIGRUNTIME void SWIG_RubyUnlinkObjects(void* ptr) {
|
||||
to the passed callback function. */
|
||||
|
||||
/* Proxy method to abstract the internal trackings datatype */
|
||||
-static int _ruby_internal_iterate_callback(void* ptr, VALUE obj, void(*meth)(void* ptr, VALUE obj)) {
|
||||
+static int swig_ruby_internal_iterate_callback(void* ptr, VALUE obj, void(*meth)(void* ptr, VALUE obj)) {
|
||||
(*meth)(ptr, obj);
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
SWIGRUNTIME void SWIG_RubyIterateTrackings( void(*meth)(void* ptr, VALUE obj) ) {
|
||||
- st_foreach(swig_ruby_trackings, (int (*)(ANYARGS))&_ruby_internal_iterate_callback, (st_data_t)meth);
|
||||
+ st_foreach(swig_ruby_trackings, (int (*)(ANYARGS))&swig_ruby_internal_iterate_callback, (st_data_t)meth);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
--
|
||||
2.4.3
|
||||
|
29
swig307-Ruby-trackings-support-for-1.8.patch
Normal file
29
swig307-Ruby-trackings-support-for-1.8.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From 604b3d009ce4ed170ebfcfb256fc5c91c08b1d0e Mon Sep 17 00:00:00 2001
|
||||
From: William S Fulton <wsf@fultondesigns.co.uk>
|
||||
Date: Sun, 13 Sep 2015 20:09:50 +0100
|
||||
Subject: [PATCH] Ruby trackings bug fix support for 1.8
|
||||
|
||||
Issue #225
|
||||
---
|
||||
Lib/ruby/rubytracking.swg | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/Lib/ruby/rubytracking.swg b/Lib/ruby/rubytracking.swg
|
||||
index 37789c1..8f9f01b 100644
|
||||
--- a/Lib/ruby/rubytracking.swg
|
||||
+++ b/Lib/ruby/rubytracking.swg
|
||||
@@ -11,6 +11,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
+#if !defined(ST_DATA_T_DEFINED)
|
||||
+/* Needs to be explicitly included for Ruby 1.8 and earlier */
|
||||
+#include <st.h>
|
||||
+#endif
|
||||
+
|
||||
/* Ruby 1.8 actually assumes the first case. */
|
||||
#if SIZEOF_VOIDP == SIZEOF_LONG
|
||||
# define SWIG2NUM(v) LONG2NUM((unsigned long)v)
|
||||
--
|
||||
2.4.3
|
||||
|
Loading…
Reference in New Issue
Block a user