Skip to content

Commit

Permalink
Merge pull request #457 from flori/prepare-3.0
Browse files Browse the repository at this point in the history
Prepare to release Ruby 3.0
  • Loading branch information
hsbt committed Dec 22, 2020
2 parents 1bd46c4 + 0c446fa commit 9e73da3
Show file tree
Hide file tree
Showing 12 changed files with 1,317 additions and 111 deletions.
4 changes: 1 addition & 3 deletions .travis.yml
Expand Up @@ -4,13 +4,11 @@ language: ruby

# Specify which ruby versions you wish to run your tests on, each version will be used
rvm:
- 2.1
- 2.2
- 2.3
- 2.4
- 2.5
- 2.6
- 2.7.0-preview3
- 2.7
- ruby-head
- jruby-9.1 # Ruby 2.3
- jruby-9.2 # Ruby 2.5
Expand Down
6 changes: 4 additions & 2 deletions Rakefile
Expand Up @@ -99,7 +99,8 @@ task(:set_env_pure) { ENV['JSON'] = 'pure' }

UndocumentedTestTask.new do |t|
t.name = 'do_test_pure'
t.libs << 'lib' << 'tests'
t.libs << 'lib' << 'tests' << 'tests/lib'
t.ruby_opts << "-rhelper"
t.test_files = FileList['tests/*_test.rb']
t.verbose = true
t.options = '-v'
Expand Down Expand Up @@ -252,7 +253,8 @@ else

UndocumentedTestTask.new do |t|
t.name = 'do_test_ext'
t.libs << 'ext' << 'lib' << 'tests'
t.libs << 'lib' << 'tests' << "tests/lib"
t.ruby_opts << '-rhelper'
t.test_files = FileList['tests/*_test.rb']
t.verbose = true
t.options = '-v'
Expand Down
18 changes: 12 additions & 6 deletions ext/json/ext/generator/generator.c
Expand Up @@ -15,8 +15,7 @@ static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
#endif
mFloat, mString, mString_Extend,
mTrueClass, mFalseClass, mNilClass, eGeneratorError,
eNestingError,
i_SAFE_STATE_PROTOTYPE;
eNestingError;

static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
Expand Down Expand Up @@ -620,13 +619,18 @@ static size_t State_memsize(const void *ptr)
return size;
}

#ifndef HAVE_RB_EXT_RACTOR_SAFE
# undef RUBY_TYPED_FROZEN_SHAREABLE
# define RUBY_TYPED_FROZEN_SHAREABLE 0
#endif

#ifdef NEW_TYPEDDATA_WRAPPER
static const rb_data_type_t JSON_Generator_State_type = {
"JSON/Generator/State",
{NULL, State_free, State_memsize,},
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
0, 0,
RUBY_TYPED_FREE_IMMEDIATELY,
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE,
#endif
};
#endif
Expand Down Expand Up @@ -1166,8 +1170,7 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts)
} else if (rb_obj_is_kind_of(opts, rb_cHash)) {
return rb_funcall(self, i_new, 1, opts);
} else {
VALUE prototype = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE);
return rb_funcall(prototype, i_dup, 0);
return rb_class_new_instance(0, NULL, cState);
}
}

Expand Down Expand Up @@ -1499,6 +1502,10 @@ static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_l
*/
void Init_generator(void)
{
#ifdef HAVE_RB_EXT_RACTOR_SAFE
rb_ext_ractor_safe(true);
#endif

#undef rb_intern
rb_require("json/common");

Expand Down Expand Up @@ -1608,5 +1615,4 @@ void Init_generator(void)
i_encoding = rb_intern("encoding");
i_encode = rb_intern("encode");
#endif
i_SAFE_STATE_PROTOTYPE = rb_intern("SAFE_STATE_PROTOTYPE");
}
65 changes: 40 additions & 25 deletions ext/json/ext/parser/parser.c
Expand Up @@ -91,13 +91,12 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)

static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
static VALUE CNaN, CInfinity, CMinusInfinity;
static VALUE cBigDecimal = Qundef;

static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
i_object_class, i_array_class, i_decimal_class, i_key_p,
i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
i_leftshift, i_new, i_BigDecimal, i_freeze, i_uminus;
i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;


#line 126 "parser.rl"
Expand Down Expand Up @@ -991,19 +990,6 @@ enum {JSON_float_en_main = 1};
#line 346 "parser.rl"


static int is_bigdecimal_class(VALUE obj)
{
if (cBigDecimal == Qundef) {
if (rb_const_defined(rb_cObject, i_BigDecimal)) {
cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal);
}
else {
return 0;
}
}
return obj == cBigDecimal;
}

static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
{
int cs = EVIL;
Expand Down Expand Up @@ -1146,21 +1132,46 @@ case 7:
#line 368 "parser.rl"

if (cs >= JSON_float_first_final) {
VALUE mod = Qnil;
ID method_id = 0;
if (rb_respond_to(json->decimal_class, i_try_convert)) {
mod = json->decimal_class;
method_id = i_try_convert;
} else if (rb_respond_to(json->decimal_class, i_new)) {
mod = json->decimal_class;
method_id = i_new;
} else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
VALUE name = rb_class_name(json->decimal_class);
const char *name_cstr = RSTRING_PTR(name);
const char *last_colon = strrchr(name_cstr, ':');
if (last_colon) {
const char *mod_path_end = last_colon - 1;
VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
mod = rb_path_to_class(mod_path);

const char *method_name_beg = last_colon + 1;
long before_len = method_name_beg - name_cstr;
long len = RSTRING_LEN(name) - before_len;
VALUE method_name = rb_str_substr(name, before_len, len);
method_id = SYM2ID(rb_str_intern(method_name));
} else {
mod = rb_mKernel;
method_id = SYM2ID(rb_str_intern(name));
}
}

long len = p - json->memo;
fbuffer_clear(json->fbuffer);
fbuffer_append(json->fbuffer, json->memo, len);
fbuffer_append_char(json->fbuffer, '\0');
if (NIL_P(json->decimal_class)) {
*result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));

if (method_id) {
VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
*result = rb_funcallv(mod, method_id, 1, &text);
} else {
VALUE text;
text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
if (is_bigdecimal_class(json->decimal_class)) {
*result = rb_funcall(Qnil, i_BigDecimal, 1, text);
} else {
*result = rb_funcall(json->decimal_class, i_new, 1, text);
}
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
}

return p + 1;
} else {
return NULL;
Expand Down Expand Up @@ -2108,6 +2119,10 @@ static VALUE cParser_source(VALUE self)

void Init_parser(void)
{
#ifdef HAVE_RB_EXT_RACTOR_SAFE
rb_ext_ractor_safe(true);
#endif

#undef rb_intern
rb_require("json/common");
mJSON = rb_define_module("JSON");
Expand Down Expand Up @@ -2150,7 +2165,7 @@ void Init_parser(void)
i_aref = rb_intern("[]");
i_leftshift = rb_intern("<<");
i_new = rb_intern("new");
i_BigDecimal = rb_intern("BigDecimal");
i_try_convert = rb_intern("try_convert");
i_freeze = rb_intern("freeze");
i_uminus = rb_intern("-@");
}
Expand Down
65 changes: 40 additions & 25 deletions ext/json/ext/parser/parser.rl
Expand Up @@ -89,13 +89,12 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)

static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
static VALUE CNaN, CInfinity, CMinusInfinity;
static VALUE cBigDecimal = Qundef;

static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
i_object_class, i_array_class, i_decimal_class, i_key_p,
i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
i_leftshift, i_new, i_BigDecimal, i_freeze, i_uminus;
i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;

%%{
machine JSON_common;
Expand Down Expand Up @@ -345,19 +344,6 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
) (^[0-9Ee.\-]? @exit );
}%%

static int is_bigdecimal_class(VALUE obj)
{
if (cBigDecimal == Qundef) {
if (rb_const_defined(rb_cObject, i_BigDecimal)) {
cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal);
}
else {
return 0;
}
}
return obj == cBigDecimal;
}

static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
{
int cs = EVIL;
Expand All @@ -367,21 +353,46 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
%% write exec;

if (cs >= JSON_float_first_final) {
VALUE mod = Qnil;
ID method_id = 0;
if (rb_respond_to(json->decimal_class, i_try_convert)) {
mod = json->decimal_class;
method_id = i_try_convert;
} else if (rb_respond_to(json->decimal_class, i_new)) {
mod = json->decimal_class;
method_id = i_new;
} else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
VALUE name = rb_class_name(json->decimal_class);
const char *name_cstr = RSTRING_PTR(name);
const char *last_colon = strrchr(name_cstr, ':');
if (last_colon) {
const char *mod_path_end = last_colon - 1;
VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
mod = rb_path_to_class(mod_path);

const char *method_name_beg = last_colon + 1;
long before_len = method_name_beg - name_cstr;
long len = RSTRING_LEN(name) - before_len;
VALUE method_name = rb_str_substr(name, before_len, len);
method_id = SYM2ID(rb_str_intern(method_name));
} else {
mod = rb_mKernel;
method_id = SYM2ID(rb_str_intern(name));
}
}

long len = p - json->memo;
fbuffer_clear(json->fbuffer);
fbuffer_append(json->fbuffer, json->memo, len);
fbuffer_append_char(json->fbuffer, '\0');
if (NIL_P(json->decimal_class)) {
*result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));

if (method_id) {
VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
*result = rb_funcallv(mod, method_id, 1, &text);
} else {
VALUE text;
text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
if (is_bigdecimal_class(json->decimal_class)) {
*result = rb_funcall(Qnil, i_BigDecimal, 1, text);
} else {
*result = rb_funcall(json->decimal_class, i_new, 1, text);
}
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
}

return p + 1;
} else {
return NULL;
Expand Down Expand Up @@ -868,6 +879,10 @@ static VALUE cParser_source(VALUE self)

void Init_parser(void)
{
#ifdef HAVE_RB_EXT_RACTOR_SAFE
rb_ext_ractor_safe(true);
#endif

#undef rb_intern
rb_require("json/common");
mJSON = rb_define_module("JSON");
Expand Down Expand Up @@ -910,7 +925,7 @@ void Init_parser(void)
i_aref = rb_intern("[]");
i_leftshift = rb_intern("<<");
i_new = rb_intern("new");
i_BigDecimal = rb_intern("BigDecimal");
i_try_convert = rb_intern("try_convert");
i_freeze = rb_intern("freeze");
i_uminus = rb_intern("-@");
}
Expand Down

0 comments on commit 9e73da3

Please sign in to comment.