Skip to content

Commit

Permalink
Merge pull request #349 from larskanis/typeddata
Browse files Browse the repository at this point in the history
Change all T_DATA objects to typed data
  • Loading branch information
larskanis authored Aug 30, 2020
2 parents 2974daf + 3b3dc1d commit 9cf9d8a
Show file tree
Hide file tree
Showing 21 changed files with 654 additions and 235 deletions.
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ matrix:
env:
- "PGVERSION=12"

- rvm: truffleruby-head
env:
- "PGVERSION=12"

- name: gem-windows
rvm: "2.7"
before_install:
Expand All @@ -43,6 +47,7 @@ matrix:
- rake gem:windows:x86-mingw32
allow_failures:
- rvm: ruby-head
- rvm: truffleruby-head
fast_finish: true

before_install:
Expand Down
1 change: 1 addition & 0 deletions ext/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
have_func 'PQresultMemorySize' # since PostgreSQL-12
have_func 'timegm'
have_func 'rb_gc_adjust_memory_usage' # since ruby-2.4
have_func 'rb_gc_mark_movable' # since ruby-2.7

# unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
have_header 'unistd.h'
Expand Down
15 changes: 14 additions & 1 deletion ext/pg.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ typedef long suseconds_t;
#define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
#endif

#ifdef HAVE_RB_GC_MARK_MOVABLE
#define pg_compact_callback(x) ((void (*)(void*))(x))
#define pg_gc_location(x) x = rb_gc_location(x)
#else
#define rb_gc_mark_movable(x) rb_gc_mark(x)
#define pg_compact_callback(x) {(x)}
#define pg_gc_location(x) UNUSED(x)
#endif

#define PG_ENC_IDX_BITS 28

/* The data behind each PG::Connection object */
Expand Down Expand Up @@ -220,6 +229,8 @@ typedef struct {
} convs[0];
} t_tmbc;

extern const rb_data_type_t pg_typemap_type;
extern const rb_data_type_t pg_coder_type;

#include "gvl_wrappers.h"

Expand Down Expand Up @@ -304,7 +315,7 @@ VALUE pg_obj_to_i _(( VALUE ));
VALUE pg_tmbc_allocate _(( void ));
void pg_coder_init_encoder _(( VALUE ));
void pg_coder_init_decoder _(( VALUE ));
void pg_coder_mark _(( t_pg_coder * ));
void pg_coder_compact _(( t_pg_coder * ));
char *pg_rb_str_ensure_capa _(( VALUE, long, char *, char ** ));

#define PG_RB_STR_ENSURE_CAPA( str, expand_len, curr_ptr, end_ptr ) \
Expand All @@ -324,6 +335,8 @@ int pg_typemap_fit_to_copy_get _(( VALUE ));
VALUE pg_typemap_result_value _(( t_typemap *, VALUE, int, int ));
t_pg_coder *pg_typemap_typecast_query_param _(( t_typemap *, VALUE, int ));
VALUE pg_typemap_typecast_copy_get _(( t_typemap *, VALUE, int, int, int ));
void pg_typemap_mark _(( t_typemap * ));
void pg_typemap_compact _(( t_typemap * ));

PGconn *pg_get_pgconn _(( VALUE ));
t_pg_connection *pg_get_connection _(( VALUE ));
Expand Down
92 changes: 65 additions & 27 deletions ext/pg_coder.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ pg_coder_allocate( VALUE klass )
void
pg_coder_init_encoder( VALUE self )
{
t_pg_coder *this = DATA_PTR( self );
t_pg_coder *this = RTYPEDDATA_DATA( self );
VALUE klass = rb_class_of(self);
if( rb_const_defined( klass, s_id_CFUNC ) ){
VALUE cfunc = rb_const_get( klass, s_id_CFUNC );
this->enc_func = DATA_PTR(cfunc);
this->enc_func = RTYPEDDATA_DATA(cfunc);
} else {
this->enc_func = NULL;
}
Expand All @@ -45,12 +45,12 @@ pg_coder_init_encoder( VALUE self )
void
pg_coder_init_decoder( VALUE self )
{
t_pg_coder *this = DATA_PTR( self );
t_pg_coder *this = RTYPEDDATA_DATA( self );
VALUE klass = rb_class_of(self);
this->enc_func = NULL;
if( rb_const_defined( klass, s_id_CFUNC ) ){
VALUE cfunc = rb_const_get( klass, s_id_CFUNC );
this->dec_func = DATA_PTR(cfunc);
this->dec_func = RTYPEDDATA_DATA(cfunc);
} else {
this->dec_func = NULL;
}
Expand All @@ -62,31 +62,57 @@ pg_coder_init_decoder( VALUE self )
}

void
pg_coder_mark(t_pg_coder *this)
pg_coder_compact(t_pg_coder *this)
{
rb_gc_mark(this->coder_obj);
pg_gc_location(this->coder_obj);
}

static void
pg_composite_coder_mark(t_pg_composite_coder *this)
pg_composite_coder_compact(t_pg_composite_coder *this)
{
pg_coder_mark(&this->comp);
pg_coder_compact(&this->comp);
}

const rb_data_type_t pg_coder_type = {
"PG::Coder",
{
(void (*)(void*))NULL,
(void (*)(void*))-1,
(size_t (*)(const void *))NULL,
pg_compact_callback(pg_coder_compact),
},
0,
0,
RUBY_TYPED_FREE_IMMEDIATELY,
};

static VALUE
pg_simple_encoder_allocate( VALUE klass )
{
t_pg_coder *this;
VALUE self = Data_Make_Struct( klass, t_pg_coder, pg_coder_mark, -1, this );
VALUE self = TypedData_Make_Struct( klass, t_pg_coder, &pg_coder_type, this );
pg_coder_init_encoder( self );
return self;
}

static const rb_data_type_t pg_composite_coder_type = {
"PG::CompositeCoder",
{
(void (*)(void*))NULL,
(void (*)(void*))-1,
(size_t (*)(const void *))NULL,
pg_compact_callback(pg_composite_coder_compact),
},
&pg_coder_type,
0,
RUBY_TYPED_FREE_IMMEDIATELY,
};

static VALUE
pg_composite_encoder_allocate( VALUE klass )
{
t_pg_composite_coder *this;
VALUE self = Data_Make_Struct( klass, t_pg_composite_coder, pg_composite_coder_mark, -1, this );
VALUE self = TypedData_Make_Struct( klass, t_pg_composite_coder, &pg_composite_coder_type, this );
pg_coder_init_encoder( self );
this->elem = NULL;
this->needs_quotation = 1;
Expand All @@ -99,7 +125,7 @@ static VALUE
pg_simple_decoder_allocate( VALUE klass )
{
t_pg_coder *this;
VALUE self = Data_Make_Struct( klass, t_pg_coder, pg_coder_mark, -1, this );
VALUE self = TypedData_Make_Struct( klass, t_pg_coder, &pg_coder_type, this );
pg_coder_init_decoder( self );
return self;
}
Expand All @@ -108,7 +134,7 @@ static VALUE
pg_composite_decoder_allocate( VALUE klass )
{
t_pg_composite_coder *this;
VALUE self = Data_Make_Struct( klass, t_pg_composite_coder, pg_composite_coder_mark, -1, this );
VALUE self = TypedData_Make_Struct( klass, t_pg_composite_coder, &pg_composite_coder_type, this );
pg_coder_init_decoder( self );
this->elem = NULL;
this->needs_quotation = 1;
Expand All @@ -135,7 +161,7 @@ pg_coder_encode(int argc, VALUE *argv, VALUE self)
VALUE value;
int len, len2;
int enc_idx;
t_pg_coder *this = DATA_PTR(self);
t_pg_coder *this = RTYPEDDATA_DATA(self);

if(argc < 1 || argc > 2){
rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..2)", argc);
Expand Down Expand Up @@ -192,7 +218,7 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
int tuple = -1;
int field = -1;
VALUE res;
t_pg_coder *this = DATA_PTR(self);
t_pg_coder *this = RTYPEDDATA_DATA(self);

if(argc < 1 || argc > 3){
rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..3)", argc);
Expand Down Expand Up @@ -230,7 +256,7 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
static VALUE
pg_coder_oid_set(VALUE self, VALUE oid)
{
t_pg_coder *this = DATA_PTR(self);
t_pg_coder *this = RTYPEDDATA_DATA(self);
this->oid = NUM2UINT(oid);
return oid;
}
Expand All @@ -245,7 +271,7 @@ pg_coder_oid_set(VALUE self, VALUE oid)
static VALUE
pg_coder_oid_get(VALUE self)
{
t_pg_coder *this = DATA_PTR(self);
t_pg_coder *this = RTYPEDDATA_DATA(self);
return UINT2NUM(this->oid);
}

Expand All @@ -261,7 +287,7 @@ pg_coder_oid_get(VALUE self)
static VALUE
pg_coder_format_set(VALUE self, VALUE format)
{
t_pg_coder *this = DATA_PTR(self);
t_pg_coder *this = RTYPEDDATA_DATA(self);
this->format = NUM2INT(format);
return format;
}
Expand All @@ -276,7 +302,7 @@ pg_coder_format_set(VALUE self, VALUE format)
static VALUE
pg_coder_format_get(VALUE self)
{
t_pg_coder *this = DATA_PTR(self);
t_pg_coder *this = RTYPEDDATA_DATA(self);
return INT2NUM(this->format);
}

Expand All @@ -292,7 +318,7 @@ pg_coder_format_get(VALUE self)
static VALUE
pg_coder_flags_set(VALUE self, VALUE flags)
{
t_pg_coder *this = DATA_PTR(self);
t_pg_coder *this = RTYPEDDATA_DATA(self);
this->flags = NUM2INT(flags);
return flags;
}
Expand All @@ -306,7 +332,7 @@ pg_coder_flags_set(VALUE self, VALUE flags)
static VALUE
pg_coder_flags_get(VALUE self)
{
t_pg_coder *this = DATA_PTR(self);
t_pg_coder *this = RTYPEDDATA_DATA(self);
return INT2NUM(this->flags);
}

Expand All @@ -323,7 +349,7 @@ pg_coder_flags_get(VALUE self)
static VALUE
pg_coder_needs_quotation_set(VALUE self, VALUE needs_quotation)
{
t_pg_composite_coder *this = DATA_PTR(self);
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
this->needs_quotation = RTEST(needs_quotation);
return needs_quotation;
}
Expand All @@ -338,7 +364,7 @@ pg_coder_needs_quotation_set(VALUE self, VALUE needs_quotation)
static VALUE
pg_coder_needs_quotation_get(VALUE self)
{
t_pg_composite_coder *this = DATA_PTR(self);
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
return this->needs_quotation ? Qtrue : Qfalse;
}

Expand All @@ -353,7 +379,7 @@ pg_coder_needs_quotation_get(VALUE self)
static VALUE
pg_coder_delimiter_set(VALUE self, VALUE delimiter)
{
t_pg_composite_coder *this = DATA_PTR(self);
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
StringValue(delimiter);
if(RSTRING_LEN(delimiter) != 1)
rb_raise( rb_eArgError, "delimiter size must be one byte");
Expand All @@ -370,7 +396,7 @@ pg_coder_delimiter_set(VALUE self, VALUE delimiter)
static VALUE
pg_coder_delimiter_get(VALUE self)
{
t_pg_composite_coder *this = DATA_PTR(self);
t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
return rb_str_new(&this->delimiter, 1);
}

Expand All @@ -386,12 +412,12 @@ pg_coder_delimiter_get(VALUE self)
static VALUE
pg_coder_elements_type_set(VALUE self, VALUE elem_type)
{
t_pg_composite_coder *this = DATA_PTR( self );
t_pg_composite_coder *this = RTYPEDDATA_DATA( self );

if ( NIL_P(elem_type) ){
this->elem = NULL;
} else if ( rb_obj_is_kind_of(elem_type, rb_cPG_Coder) ){
this->elem = DATA_PTR( elem_type );
this->elem = RTYPEDDATA_DATA( elem_type );
} else {
rb_raise( rb_eTypeError, "wrong elements type %s (expected some kind of PG::Coder)",
rb_obj_classname( elem_type ) );
Expand All @@ -401,10 +427,22 @@ pg_coder_elements_type_set(VALUE self, VALUE elem_type)
return elem_type;
}

static const rb_data_type_t pg_coder_cfunc_type = {
"PG::Coder::CFUNC",
{
(void (*)(void*))NULL,
(void (*)(void*))NULL,
(size_t (*)(const void *))NULL,
},
0,
0,
RUBY_TYPED_FREE_IMMEDIATELY,
};

void
pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
{
VALUE cfunc_obj = Data_Wrap_Struct( rb_cObject, NULL, NULL, func );
VALUE cfunc_obj = TypedData_Wrap_Struct( rb_cObject, &pg_coder_cfunc_type, func );
VALUE coder_klass = rb_define_class_under( nsp, name, base_klass );
if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_BinaryDecoder )
rb_include_module( coder_klass, rb_mPG_BinaryFormatting );
Expand Down
Loading

0 comments on commit 9cf9d8a

Please sign in to comment.