Skip to content

Commit

Permalink
Stop using the deprecated Data_* API (#905)
Browse files Browse the repository at this point in the history
* Convert cache objects to TypedData API

The replacement API was introduced in Ruby 1.9.2 (2010),
and the old untyped data API was marked a deprecated in the documentation
as of Ruby 2.3.0 (2015)

Ref: https://bugs.ruby-lang.org/issues/19998

* Convert parser objects to TypedData API

The replacement API was introduced in Ruby 1.9.2 (2010),
and the old untyped data API was marked a deprecated in the documentation
as of Ruby 2.3.0 (2015)

Ref: https://bugs.ruby-lang.org/issues/19998

* Convert encoder objects to TypedData API

The replacement API was introduced in Ruby 1.9.2 (2010),
and the old untyped data API was marked a deprecated in the documentation
as of Ruby 2.3.0 (2015)

Ref: https://bugs.ruby-lang.org/issues/19998

* Convert StringWriter and StreamWriter objects to TypedData API

The replacement API was introduced in Ruby 1.9.2 (2010),
and the old untyped data API was marked a deprecated in the documentation
as of Ruby 2.3.0 (2015)

Ref: https://bugs.ruby-lang.org/issues/19998

* Convert Stack objects to TypedData API

The replacement API was introduced in Ruby 1.9.2 (2010),
and the old untyped data API was marked a deprecated in the documentation
as of Ruby 2.3.0 (2015)

Ref: https://bugs.ruby-lang.org/issues/19998

* Remove useless DATA_PTR call and appease clang-format

---------

Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
  • Loading branch information
casperisfine and byroot committed Dec 5, 2023
1 parent e2825f7 commit 67c20f5
Show file tree
Hide file tree
Showing 11 changed files with 202 additions and 69 deletions.
6 changes: 4 additions & 2 deletions ext/oj/cache.c
Expand Up @@ -260,7 +260,8 @@ void cache_set_expunge_rate(Cache c, int rate) {
c->xrate = (uint8_t)rate;
}

void cache_free(Cache c) {
void cache_free(void *data) {
Cache c = (Cache)data;
uint64_t i;

for (i = 0; i < c->size; i++) {
Expand All @@ -276,7 +277,8 @@ void cache_free(Cache c) {
OJ_FREE(c);
}

void cache_mark(Cache c) {
void cache_mark(void *data) {
Cache c = (Cache)data;
uint64_t i;

#if !HAVE_PTHREAD_MUTEX_INIT
Expand Down
5 changes: 3 additions & 2 deletions ext/oj/cache.h
Expand Up @@ -10,10 +10,11 @@
#define CACHE_MAX_KEY 35

struct _cache;
typedef struct _cache *Cache;

extern struct _cache *cache_create(size_t size, VALUE (*form)(const char *str, size_t len), bool mark, bool locking);
extern void cache_free(struct _cache *c);
extern void cache_mark(struct _cache *c);
extern void cache_free(void *data);
extern void cache_mark(void *data);
extern void cache_set_form(struct _cache *c, VALUE (*form)(const char *str, size_t len));
extern VALUE cache_intern(struct _cache *c, const char *key, size_t len);
extern void cache_set_expunge_rate(struct _cache *c, int rate);
Expand Down
7 changes: 5 additions & 2 deletions ext/oj/dump.c
Expand Up @@ -727,8 +727,11 @@ static void debug_raise(const char *orig, size_t cnt, int line) {

void oj_dump_raw_json(VALUE obj, int depth, Out out) {
if (oj_string_writer_class == rb_obj_class(obj)) {
StrWriter sw = (StrWriter)DATA_PTR(obj);
size_t len = sw->out.cur - sw->out.buf;
StrWriter sw;
size_t len;

sw = oj_str_writer_unwrap(obj);
len = sw->out.cur - sw->out.buf;

if (0 < len) {
len--;
Expand Down
13 changes: 7 additions & 6 deletions ext/oj/fast.c
Expand Up @@ -780,11 +780,10 @@ static VALUE parse_json(VALUE clas, char *json, bool given) {
}
}
#endif
doc->json = json;
self = TypedData_Wrap_Struct(clas, &oj_doc_type, doc);
doc->self = self;
DATA_PTR(doc->self) = doc;
result = rb_protect(protect_open_proc, (VALUE)&pi, &ex);
doc->json = json;
self = TypedData_Wrap_Struct(clas, &oj_doc_type, doc);
doc->self = self;
result = rb_protect(protect_open_proc, (VALUE)&pi, &ex);
if (given || 0 != ex) {
DATA_PTR(doc->self) = NULL;
// TBD is this needed?
Expand Down Expand Up @@ -1609,7 +1608,9 @@ static VALUE doc_dump(int argc, VALUE *argv, VALUE self) {
* Oj::Doc.open('[1,2,3]') { |doc| doc.size() } #=> 4
*/
static VALUE doc_size(VALUE self) {
return ULONG2NUM(((Doc)DATA_PTR(self))->size);
Doc d;
TypedData_Get_Struct(self, struct _doc, &oj_doc_type, d);
return ULONG2NUM(d->size);
}

/* @overload close() => nil
Expand Down
29 changes: 23 additions & 6 deletions ext/oj/intern.c
Expand Up @@ -85,20 +85,31 @@ static VALUE form_attr(const char *str, size_t len) {
return (VALUE)rb_intern3(buf, len + 1, oj_utf8_encoding);
}

static const rb_data_type_t oj_cache_type = {
"Oj/cache",
{
cache_mark,
cache_free,
NULL,
},
0,
0,
};

void oj_hash_init(void) {
VALUE cache_class = rb_define_class_under(Oj, "Cache", rb_cObject);
rb_undef_alloc_func(cache_class);

struct _cache *str_cache = cache_create(0, form_str, true, true);
str_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, str_cache);
str_cache_obj = TypedData_Wrap_Struct(cache_class, &oj_cache_type, str_cache);
rb_gc_register_address(&str_cache_obj);

struct _cache *sym_cache = cache_create(0, form_sym, true, true);
sym_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, sym_cache);
sym_cache_obj = TypedData_Wrap_Struct(cache_class, &oj_cache_type, sym_cache);
rb_gc_register_address(&sym_cache_obj);

struct _cache *attr_cache = cache_create(0, form_attr, false, true);
attr_cache_obj = Data_Wrap_Struct(cache_class, cache_mark, cache_free, attr_cache);
attr_cache_obj = TypedData_Wrap_Struct(cache_class, &oj_cache_type, attr_cache);
rb_gc_register_address(&attr_cache_obj);

memset(class_hash.slots, 0, sizeof(class_hash.slots));
Expand All @@ -118,17 +129,23 @@ oj_str_intern(const char *key, size_t len) {
#if HAVE_RB_ENC_INTERNED_STR && 0
return rb_enc_interned_str(key, len, rb_utf8_encoding());
#else
return cache_intern(DATA_PTR(str_cache_obj), key, len);
Cache c;
TypedData_Get_Struct(str_cache_obj, struct _cache, &oj_cache_type, c);
return cache_intern(c, key, len);
#endif
}

VALUE
oj_sym_intern(const char *key, size_t len) {
return cache_intern(DATA_PTR(sym_cache_obj), key, len);
Cache c;
TypedData_Get_Struct(sym_cache_obj, struct _cache, &oj_cache_type, c);
return cache_intern(c, key, len);
}

ID oj_attr_intern(const char *key, size_t len) {
return cache_intern(DATA_PTR(attr_cache_obj), key, len);
Cache c;
TypedData_Get_Struct(attr_cache_obj, struct _cache, &oj_cache_type, c);
return cache_intern(c, key, len);
}

static uint64_t hash_calc(const uint8_t *key, size_t len) {
Expand Down
2 changes: 2 additions & 0 deletions ext/oj/oj.h
Expand Up @@ -262,6 +262,8 @@ extern void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out);
extern void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts);
extern char *oj_longlong_to_string(long long num, bool negative, char *buf);

extern StrWriter oj_str_writer_unwrap(VALUE writer);

extern void oj_str_writer_push_key(StrWriter sw, const char *key);
extern void oj_str_writer_push_object(StrWriter sw, const char *key);
extern void oj_str_writer_push_array(StrWriter sw, const char *key);
Expand Down
49 changes: 37 additions & 12 deletions ext/oj/parser.c
Expand Up @@ -1164,6 +1164,17 @@ static void parser_mark(void *ptr) {
}
}

static const rb_data_type_t oj_parser_type = {
"Oj/parser",
{
parser_mark,
parser_free,
NULL,
},
0,
0,
};

extern void oj_set_parser_validator(ojParser p);
extern void oj_set_parser_saj(ojParser p);
extern void oj_set_parser_usual(ojParser p);
Expand Down Expand Up @@ -1255,7 +1266,7 @@ static VALUE parser_new(int argc, VALUE *argv, VALUE self) {
rb_hash_foreach(ropts, opt_cb, (VALUE)p);
}
}
return Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
return TypedData_Wrap_Struct(parser_class, &oj_parser_type, p);
}

// Create a new parser without setting the delegate. The parser is
Expand All @@ -1275,7 +1286,7 @@ VALUE oj_parser_new(void) {
buf_init(&p->buf);
p->map = value_map;

return Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
return TypedData_Wrap_Struct(parser_class, &oj_parser_type, p);
}

// Set set the options from a hash (ropts).
Expand Down Expand Up @@ -1322,11 +1333,13 @@ void oj_parser_set_option(ojParser p, VALUE ropts) {
* - _symbol_keys_ is a flag that indicates Hash keys should be parsed to Symbols versus Strings.
*/
static VALUE parser_missing(int argc, VALUE *argv, VALUE self) {
ojParser p = (ojParser)DATA_PTR(self);
ojParser p;
const char *key = NULL;
volatile VALUE rkey = *argv;
volatile VALUE rv = Qnil;

TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);

#if HAVE_RB_EXT_RACTOR_SAFE
// This doesn't seem to do anything.
rb_ext_ractor_safe(true);
Expand All @@ -1352,9 +1365,11 @@ static VALUE parser_missing(int argc, VALUE *argv, VALUE self) {
* Returns the result according to the delegate of the parser.
*/
static VALUE parser_parse(VALUE self, VALUE json) {
ojParser p = (ojParser)DATA_PTR(self);
ojParser p;
const byte *ptr = (const byte *)StringValuePtr(json);

TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);

parser_reset(p);
p->start(p);
parse(p, ptr);
Expand All @@ -1368,9 +1383,11 @@ static VALUE load_rescue(VALUE self, VALUE x) {
}

static VALUE load(VALUE self) {
ojParser p = (ojParser)DATA_PTR(self);
ojParser p;
volatile VALUE rbuf = rb_str_new2("");

TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);

p->start(p);
while (true) {
rb_funcall(p->reader, oj_readpartial_id, 2, INT2NUM(16385), rbuf);
Expand All @@ -1389,7 +1406,9 @@ static VALUE load(VALUE self) {
* Returns the result according to the delegate of the parser.
*/
static VALUE parser_load(VALUE self, VALUE reader) {
ojParser p = (ojParser)DATA_PTR(self);
ojParser p;

TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);

parser_reset(p);
p->reader = reader;
Expand All @@ -1406,10 +1425,12 @@ static VALUE parser_load(VALUE self, VALUE reader) {
* Returns the result according to the delegate of the parser.
*/
static VALUE parser_file(VALUE self, VALUE filename) {
ojParser p = (ojParser)DATA_PTR(self);
ojParser p;
const char *path;
int fd;

TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);

path = StringValuePtr(filename);

parser_reset(p);
Expand Down Expand Up @@ -1453,7 +1474,9 @@ static VALUE parser_file(VALUE self, VALUE filename) {
* Returns the current state of the just_one [_Boolean_] option.
*/
static VALUE parser_just_one(VALUE self) {
ojParser p = (ojParser)DATA_PTR(self);
ojParser p;

TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);

return p->just_one ? Qtrue : Qfalse;
}
Expand All @@ -1467,7 +1490,9 @@ static VALUE parser_just_one(VALUE self) {
* Returns the current state of the just_one [_Boolean_] option.
*/
static VALUE parser_just_one_set(VALUE self, VALUE v) {
ojParser p = (ojParser)DATA_PTR(self);
ojParser p;

TypedData_Get_Struct(self, struct _ojParser, &oj_parser_type, p);

p->just_one = (Qtrue == v);

Expand All @@ -1491,7 +1516,7 @@ static VALUE parser_usual(VALUE self) {
buf_init(&p->buf);
p->map = value_map;
oj_set_parser_usual(p);
usual_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
usual_parser = TypedData_Wrap_Struct(parser_class, &oj_parser_type, p);
rb_gc_register_address(&usual_parser);
}
return usual_parser;
Expand All @@ -1514,7 +1539,7 @@ static VALUE parser_saj(VALUE self) {
buf_init(&p->buf);
p->map = value_map;
oj_set_parser_saj(p);
saj_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
saj_parser = TypedData_Wrap_Struct(parser_class, &oj_parser_type, p);
rb_gc_register_address(&saj_parser);
}
return saj_parser;
Expand All @@ -1536,7 +1561,7 @@ static VALUE parser_validate(VALUE self) {
buf_init(&p->buf);
p->map = value_map;
oj_set_parser_validator(p);
validate_parser = Data_Wrap_Struct(parser_class, parser_mark, parser_free, p);
validate_parser = TypedData_Wrap_Struct(parser_class, &oj_parser_type, p);
rb_gc_register_address(&validate_parser);
}
return validate_parser;
Expand Down
29 changes: 23 additions & 6 deletions ext/oj/rails.c
Expand Up @@ -639,6 +639,17 @@ static void encoder_mark(void *ptr) {
}
}

static const rb_data_type_t oj_encoder_type = {
"Oj/encoder",
{
encoder_mark,
encoder_free,
NULL,
},
0,
0,
};

/* Document-method: new
* call-seq: new(options=nil)
*
Expand All @@ -656,7 +667,7 @@ static VALUE encoder_new(int argc, VALUE *argv, VALUE self) {
oj_parse_options(*argv, &e->opts);
e->arg = *argv;
}
return Data_Wrap_Struct(encoder_class, encoder_mark, encoder_free, e);
return TypedData_Wrap_Struct(encoder_class, &oj_encoder_type, e);
}

static VALUE resolve_classpath(const char *name) {
Expand Down Expand Up @@ -748,7 +759,8 @@ static void optimize(int argc, VALUE *argv, ROptTable rot, bool on) {
* - *classes* [_Class_] a list of classes to optimize
*/
static VALUE encoder_optimize(int argc, VALUE *argv, VALUE self) {
Encoder e = (Encoder)DATA_PTR(self);
Encoder e;
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);

optimize(argc, argv, &e->ropts, true);

Expand Down Expand Up @@ -804,7 +816,8 @@ rails_mimic_json(VALUE self) {
* - *classes* [_Class_] a list of classes to deoptimize
*/
static VALUE encoder_deoptimize(int argc, VALUE *argv, VALUE self) {
Encoder e = (Encoder)DATA_PTR(self);
Encoder e;
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);

optimize(argc, argv, &e->ropts, false);

Expand Down Expand Up @@ -833,8 +846,11 @@ static VALUE rails_deoptimize(int argc, VALUE *argv, VALUE self) {
* @return true if the class is being optimized for rails and false otherwise
*/
static VALUE encoder_optimized(VALUE self, VALUE clas) {
Encoder e = (Encoder)DATA_PTR(self);
ROpt ro = oj_rails_get_opt(&e->ropts, clas);
Encoder e;
ROpt ro;

TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);
ro = oj_rails_get_opt(&e->ropts, clas);

if (NULL == ro) {
return Qfalse;
Expand Down Expand Up @@ -940,7 +956,8 @@ static VALUE encode(VALUE obj, ROptTable ropts, Options opts, int argc, VALUE *a
* Returns encoded object as a JSON string.
*/
static VALUE encoder_encode(VALUE self, VALUE obj) {
Encoder e = (Encoder)DATA_PTR(self);
Encoder e;
TypedData_Get_Struct(self, struct _encoder, &oj_encoder_type, e);

if (Qnil != e->arg) {
VALUE argv[1] = {e->arg};
Expand Down

0 comments on commit 67c20f5

Please sign in to comment.