Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare to release Ruby 3.0 #457

Merged
merged 13 commits into from
Dec 22, 2020
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading