1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
/* -----------------------------------------------------------------------------
* rubytracking.swg
*
* This file contains support for tracking mappings from
* Ruby objects to C++ objects. This functionality is needed
* to implement mark functions for Ruby's mark and sweep
* garbage collector.
* ----------------------------------------------------------------------------- */
#ifdef __cplusplus
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)
# define NUM2SWIG(x) (unsigned long)NUM2LONG(x)
#elif SIZEOF_VOIDP == SIZEOF_LONG_LONG
# define SWIG2NUM(v) LL2NUM((unsigned long long)v)
# define NUM2SWIG(x) (unsigned long long)NUM2LL(x)
#else
# error sizeof(void*) is not the same as long or long long
#endif
/* Global hash table to store Trackings from C/C++
structs to Ruby Objects.
*/
static st_table* swig_ruby_trackings = NULL;
static VALUE swig_ruby_trackings_count(ANYARGS) {
return SWIG2NUM(swig_ruby_trackings->num_entries);
}
/* Setup a hash table to store Trackings */
SWIGRUNTIME void SWIG_RubyInitializeTrackings(void) {
/* Create a hash table to store Trackings from C++
objects to Ruby objects. */
/* Try to see if some other .so has already created a
tracking hash table, which we keep hidden in an instance var
in the SWIG module.
This is done to allow multiple DSOs to share the same
tracking table.
*/
VALUE trackings_value = Qnil;
/* change the variable name so that we can mix modules
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);
trackings_value = rb_ivar_get( _mSWIG, trackings_id );
rb_gv_set("VERBOSE", verbose);
/* 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);
}
rb_define_virtual_variable("SWIG_TRACKINGS_COUNT", swig_ruby_trackings_count, NULL);
}
/* Add a Tracking from a C/C++ struct to a Ruby object */
SWIGRUNTIME void SWIG_RubyAddTracking(void* ptr, VALUE object) {
/* Store the mapping to the global hash table. */
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) {
/* Now lookup the value stored in the global hash table */
VALUE value;
if (st_lookup(swig_ruby_trackings, (st_data_t)ptr, &value)) {
return value;
} else {
return Qnil;
}
}
/* Remove a Tracking from a C/C++ struct to a Ruby object. It
is very important to remove objects once they are destroyed
since the same memory address may be reused later to create
a new object. */
SWIGRUNTIME void SWIG_RubyRemoveTracking(void* ptr) {
/* 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
underlying C++ object. This is needed if the lifetime of the
Ruby object is longer than the C++ object */
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 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))&swig_ruby_internal_iterate_callback, (st_data_t)meth);
}
#ifdef __cplusplus
}
#endif
|