Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 39 additions & 56 deletions ext/objspace/objspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,28 +295,27 @@ size_t rb_sym_immortal_count(void);

/*
* call-seq:
* ObjectSpace.count_symbols([result_hash]) -> hash
* ObjectSpace.count_symbols(result_hash = nil) -> hash
*
* Counts symbols for each Symbol type.
* Returns a hash containing the number of objects for each Symbol type.
*
* This method is only for MRI developers interested in performance and memory
* usage of Ruby programs.
* The types of Symbols are the following:
*
* If the optional argument, result_hash, is given, it is overwritten and
* returned. This is intended to avoid probe effect.
* - +mortal_dynamic_symbol+: Symbols that are garbage collectable.
* - +immortal_dynamic_symbol+: Symbols that are objects allocated from the
* garbage collector, but are not garbage collectable.
* - +immortal_static_symbol+: Symbols that are not allocated from the
* garbage collector, and are thus not garbage collectable.
* - +immortal_symbol+: the sum of +immortal_dynamic_symbol+ and +immortal_static_symbol+.
*
* Note:
* The contents of the returned hash is implementation defined.
* It may be changed in future.
*
* This method is only expected to work with C Ruby.
* If the optional argument +result_hash+ is given, it is overwritten and
* returned. This is intended to avoid the probe effect.
*
* On this version of MRI, they have 3 types of Symbols (and 1 total counts).
* This method is intended for developers interested in performance and memory
* usage of Ruby programs. The contents of the returned hash is implementation
* specific and may change in the future.
*
* * mortal_dynamic_symbol: GC target symbols (collected by GC)
* * immortal_dynamic_symbol: Immortal symbols promoted from dynamic symbols (do not collected by GC)
* * immortal_static_symbol: Immortal symbols (do not collected by GC)
* * immortal_symbol: total immortal symbols (immortal_dynamic_symbol+immortal_static_symbol)
* This method is only expected to work with C Ruby.
*/

static VALUE
Expand Down Expand Up @@ -365,32 +364,22 @@ cto_i(VALUE v, void *data)

/*
* call-seq:
* ObjectSpace.count_tdata_objects([result_hash]) -> hash
*
* Counts objects for each +T_DATA+ type.
*
* This method is only for MRI developers interested in performance and memory
* usage of Ruby programs.
* ObjectSpace.count_tdata_objects(result_hash = nil) -> hash
*
* It returns a hash as:
*
* {RubyVM::InstructionSequence=>504, :parser=>5, :barrier=>6,
* :mutex=>6, Proc=>60, RubyVM::Env=>57, Mutex=>1, Encoding=>99,
* ThreadGroup=>1, Binding=>1, Thread=>1, RubyVM=>1, :iseq=>1,
* Random=>1, ARGF.class=>1, Data=>1, :autoload=>3, Time=>2}
* # T_DATA objects existing at startup on r32276.
* Returns a hash containing the number of objects for each +T_DATA+ type.
* The keys are Class objects when the +T_DATA+ object has an associated class,
* or Symbol objects of the name defined in the +rb_data_type_struct+ for internal
* +T_DATA+ objects.
*
* If the optional argument, result_hash, is given, it is overwritten and
* returned. This is intended to avoid probe effect.
* ObjectSpace.count_tdata_objects
* # => {RBS::Location => 39255, marshal_compat_table: 1, Encoding => 103, mutex: 1, ... }
*
* The contents of the returned hash is implementation specific and may change
* in the future.
* If the optional argument +result_hash+ is given, it is overwritten and
* returned. This is intended to avoid the probe effect.
*
* In this version, keys are Class object or Symbol object.
*
* If object is kind of normal (accessible) object, the key is Class object.
* If object is not a kind of normal (internal) object, the key is symbol
* name, registered by rb_data_type_struct.
* This method is intended for developers interested in performance and memory
* usage of Ruby programs. The contents of the returned hash is implementation
* specific and may change in the future.
*
* This method is only expected to work with C Ruby.
*/
Expand Down Expand Up @@ -429,28 +418,22 @@ count_imemo_objects_i(VALUE v, void *data)

/*
* call-seq:
* ObjectSpace.count_imemo_objects([result_hash]) -> hash
*
* Counts objects for each +T_IMEMO+ type.
*
* This method is only for MRI developers interested in performance and memory
* usage of Ruby programs.
*
* It returns a hash as:
* ObjectSpace.count_imemo_objects(result_hash = nil) -> hash
*
* {:imemo_ifunc=>8,
* :imemo_svar=>7,
* :imemo_cref=>509,
* :imemo_memo=>1,
* :imemo_throw_data=>1}
* Returns a hash containing the number of objects for each +T_IMEMO+ type.
* The keys are Symbol objects of the +T_IMEMO+ type name.
* +T_IMEMO+ objects are Ruby internal objects that are not visible to Ruby
* programs.
*
* If the optional argument, result_hash, is given, it is overwritten and
* returned. This is intended to avoid probe effect.
* ObjectSpace.count_imemo_objects
* # => {imemo_callcache: 5482, imemo_constcache: 1258, imemo_ment: 13906, ... }
*
* The contents of the returned hash is implementation specific and may change
* in the future.
* If the optional argument +result_hash+ is given, it is overwritten and
* returned. This is intended to avoid the probe effect.
*
* In this version, keys are symbol objects.
* This method is intended for developers interested in performance and memory
* usage of Ruby programs. The contents of the returned hash is implementation
* specific and may change in the future.
*
* This method is only expected to work with C Ruby.
*/
Expand Down
8 changes: 6 additions & 2 deletions prism/prism.c
Original file line number Diff line number Diff line change
Expand Up @@ -3962,9 +3962,13 @@ pm_float_node_rational_create(pm_parser_t *parser, const pm_token_t *token) {
memcpy(digits + (point - start), point + 1, (unsigned long) (end - point - 1));
pm_integer_parse(&node->numerator, PM_INTEGER_BASE_DEFAULT, digits, digits + length - 1);

size_t fract_length = 0;
for (const uint8_t *fract = point; fract < end; ++fract) {
if (*fract != '_') ++fract_length;
}
digits[0] = '1';
if (end - point > 1) memset(digits + 1, '0', (size_t) (end - point - 1));
pm_integer_parse(&node->denominator, PM_INTEGER_BASE_DEFAULT, digits, digits + (end - point));
if (fract_length > 1) memset(digits + 1, '0', fract_length - 1);
pm_integer_parse(&node->denominator, PM_INTEGER_BASE_DEFAULT, digits, digits + fract_length);
xfree(digits);

pm_integers_reduce(&node->numerator, &node->denominator);
Expand Down
11 changes: 11 additions & 0 deletions test/prism/result/numeric_value_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,27 @@ module Prism
class NumericValueTest < TestCase
def test_numeric_value
assert_equal 123, Prism.parse_statement("123").value
assert_equal 123, Prism.parse_statement("1_23").value
assert_equal 3.14, Prism.parse_statement("3.14").value
assert_equal 3.14, Prism.parse_statement("3.1_4").value
assert_equal 42i, Prism.parse_statement("42i").value
assert_equal 42i, Prism.parse_statement("4_2i").value
assert_equal 42.1ri, Prism.parse_statement("42.1ri").value
assert_equal 42.1ri, Prism.parse_statement("42.1_0ri").value
assert_equal 3.14i, Prism.parse_statement("3.14i").value
assert_equal 3.14i, Prism.parse_statement("3.1_4i").value
assert_equal 42r, Prism.parse_statement("42r").value
assert_equal 42r, Prism.parse_statement("4_2r").value
assert_equal 0.5r, Prism.parse_statement("0.5r").value
assert_equal 0.5r, Prism.parse_statement("0.5_0r").value
assert_equal 42ri, Prism.parse_statement("42ri").value
assert_equal 42ri, Prism.parse_statement("4_2ri").value
assert_equal 0.5ri, Prism.parse_statement("0.5ri").value
assert_equal 0.5ri, Prism.parse_statement("0.5_0ri").value
assert_equal 0xFFr, Prism.parse_statement("0xFFr").value
assert_equal 0xFFr, Prism.parse_statement("0xF_Fr").value
assert_equal 0xFFri, Prism.parse_statement("0xFFri").value
assert_equal 0xFFri, Prism.parse_statement("0xF_Fri").value
end
end
end
5 changes: 5 additions & 0 deletions test/ruby/test_literal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,11 @@ def test_float
$VERBOSE = verbose_bak
end

def test_rational_float
assert_equal(12, 0.12r * 100)
assert_equal(12, 0.1_2r * 100)
end

def test_symbol_list
assert_equal([:foo, :bar], %i[foo bar])
assert_equal([:"\"foo"], %i["foo])
Expand Down