<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/test/ripper/test_ripper.rb, branch v4.0.3</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>[Bug #21004] Fix memory leak with "it" in parse.y</title>
<updated>2025-01-05T00:06:12+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2025-01-04T22:02:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=dfc9e978fba886d9a9175534551b1fc7b4d22abd'/>
<id>dfc9e978fba886d9a9175534551b1fc7b4d22abd</id>
<content type='text'>
Parsing `-&gt; do it end` in parse.y leaks memory. We can see this in the
Valgrind output:

    56 bytes in 1 blocks are definitely lost in loss record 1 of 6
        at 0x484E0DC: calloc (vg_replace_malloc.c:1675)
        by 0x188970: calloc1 (default.c:1472)
        by 0x188970: rb_gc_impl_calloc (default.c:8208)
        by 0x188970: ruby_xcalloc_body (gc.c:4598)
        by 0x18B8BC: ruby_xcalloc (gc.c:4592)
        by 0x21DCCA70: new_locations_lambda_body (ripper.y:12844)
        by 0x21DCCA70: ripper_yyparse (ripper.y:5194)
        by 0x21DDA521: rb_ruby_ripper_parse0 (ripper.y:15798)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Parsing `-&gt; do it end` in parse.y leaks memory. We can see this in the
Valgrind output:

    56 bytes in 1 blocks are definitely lost in loss record 1 of 6
        at 0x484E0DC: calloc (vg_replace_malloc.c:1675)
        by 0x188970: calloc1 (default.c:1472)
        by 0x188970: rb_gc_impl_calloc (default.c:8208)
        by 0x188970: ruby_xcalloc_body (gc.c:4598)
        by 0x18B8BC: ruby_xcalloc (gc.c:4592)
        by 0x21DCCA70: new_locations_lambda_body (ripper.y:12844)
        by 0x21DCCA70: ripper_yyparse (ripper.y:5194)
        by 0x21DDA521: rb_ruby_ripper_parse0 (ripper.y:15798)
</pre>
</div>
</content>
</entry>
<entry>
<title>[Bug #20504] Move dynamic regexp concatenation to iseq compiler</title>
<updated>2025-01-03T01:25:15+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2025-01-03T01:25:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=6bbb470dc77a671c67411a5d3a2564bd0a665a9c'/>
<id>6bbb470dc77a671c67411a5d3a2564bd0a665a9c</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Ripper: Fix duplicate regexp errors</title>
<updated>2024-12-28T02:35:00+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2024-12-28T02:35:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=0ccc7657f3f51d973eac5f846d1594062838a2c9'/>
<id>0ccc7657f3f51d973eac5f846d1594062838a2c9</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>[Bug #20989] Ripper: Pass `compile_error`</title>
<updated>2024-12-28T02:25:57+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2024-12-28T02:25:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=fb18bb183c24ca82b8f114ed090d62bd69b5df84'/>
<id>fb18bb183c24ca82b8f114ed090d62bd69b5df84</id>
<content type='text'>
For the universal parser, `rb_parser_reg_fragment_check` function is
shared between the parser and ripper.  However `parser_params` struct
is partially different, and `compile_error` function depends on that
part indirectly.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
For the universal parser, `rb_parser_reg_fragment_check` function is
shared between the parser and ripper.  However `parser_params` struct
is partially different, and `compile_error` function depends on that
part indirectly.
</pre>
</div>
</content>
</entry>
<entry>
<title>[Bug #20969] Pass `assignable` from ripper</title>
<updated>2024-12-19T14:20:09+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2024-12-19T14:20:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=7b2ae8df905d7bbc084d31a8f55cecc7e7c422b3'/>
<id>7b2ae8df905d7bbc084d31a8f55cecc7e7c422b3</id>
<content type='text'>
For the universal parser, `rb_reg_named_capture_assign_iter_impl`
function is shared between the parser and ripper.  However
`parser_params` struct is partially different, and `assignable`
function depends on that part indirectly.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
For the universal parser, `rb_reg_named_capture_assign_iter_impl`
function is shared between the parser and ripper.  However
`parser_params` struct is partially different, and `assignable`
function depends on that part indirectly.
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix memory leak in Ripper.sexp</title>
<updated>2024-05-01T15:09:54+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2024-05-01T14:01:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=7ef8bb129ff16750429a7ede4397d0622954ca35'/>
<id>7ef8bb129ff16750429a7ede4397d0622954ca35</id>
<content type='text'>
rb_ast_dispose does not free the rb_ast_t causing it to be leaked. This
commit changes it to use rb_ast_free instead.

For example:

    require "ripper"

    10.times do
      100_000.times do
        Ripper.sexp("")
      end

      puts `ps -o rss= -p #{$$}`
    end

Before:

    27648
    32512
    37376
    42240
    47232
    52224
    57344
    62208
    67072
    71936

After:

    22784
    22784
    22784
    22784
    22912
    22912
    22912
    22912
    22912
    22912
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
rb_ast_dispose does not free the rb_ast_t causing it to be leaked. This
commit changes it to use rb_ast_free instead.

For example:

    require "ripper"

    10.times do
      100_000.times do
        Ripper.sexp("")
      end

      puts `ps -o rss= -p #{$$}`
    end

Before:

    27648
    32512
    37376
    42240
    47232
    52224
    57344
    62208
    67072
    71936

After:

    22784
    22784
    22784
    22784
    22912
    22912
    22912
    22912
    22912
    22912
</pre>
</div>
</content>
</entry>
<entry>
<title>[Feature #20257] Rearchitect Ripper</title>
<updated>2024-02-20T08:33:58+00:00</updated>
<author>
<name>yui-knk</name>
<email>spiketeika@gmail.com</email>
</author>
<published>2024-01-12T01:46:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=89cfc1520717257073012ec07105c551e4b8af7c'/>
<id>89cfc1520717257073012ec07105c551e4b8af7c</id>
<content type='text'>
Introduce another semantic value stack for Ripper so that
Ripper can manage both Node and Ruby Object separately.
This rearchitectutre of Ripper solves these issues.
Therefore adding test cases for them.

* [Bug 10436] https://bugs.ruby-lang.org/issues/10436
* [Bug 18988] https://bugs.ruby-lang.org/issues/18988
* [Bug 20055] https://bugs.ruby-lang.org/issues/20055

Checked the differences of `Ripper.sexp` for files under `/test/ruby`
are only on test_pattern_matching.rb.
The differences comes from the differences between
`new_hash_pattern_tail` functions between parser and Ripper.
Ripper `new_hash_pattern_tail` didn’t call `assignable` then
`kw_rest_arg` wasn’t marked as local variable.
This is also fixed by this commit.

```
--- a/./tmp/before/test_pattern_matching.rb
+++ b/./tmp/after/test_pattern_matching.rb
@@ -3607,7 +3607,7 @@
                  [:in,
                   [:hshptn, nil, [], [:var_field, [:@ident, “a”, [984, 13]]]],
                   [[:binary,
-                    [:vcall, [:@ident, “a”, [985, 10]]],
+                    [:var_ref, [:@ident, “a”, [985, 10]]],
                     :==,
                     [:hash, nil]]],
                   nil]]],
@@ -3662,7 +3662,7 @@
                  [:in,
                   [:hshptn, nil, [], [:var_field, [:@ident, “a”, [993, 13]]]],
                   [[:binary,
-                    [:vcall, [:@ident, “a”, [994, 10]]],
+                    [:var_ref, [:@ident, “a”, [994, 10]]],
                     :==,
                     [:hash,
                      [:assoclist_from_args,
@@ -3813,7 +3813,7 @@
                    [:command,
                     [:@ident, “raise”, [1022, 10]],
                     [:args_add_block,
-                     [[:vcall, [:@ident, “b”, [1022, 16]]]],
+                     [[:var_ref, [:@ident, “b”, [1022, 16]]]],
                      false]]],
                   [:else, [[:var_ref, [:@kw, “true”, [1024, 10]]]]]]]],
                nil,
@@ -3876,7 +3876,7 @@
                      [:@int, “0”, [1033, 15]]],
                     :“&amp;&amp;“,
                     [:binary,
-                     [:vcall, [:@ident, “b”, [1033, 20]]],
+                     [:var_ref, [:@ident, “b”, [1033, 20]]],
                      :==,
                      [:hash, nil]]]],
                   nil]]],
@@ -3946,7 +3946,7 @@
                      [:@int, “0”, [1042, 15]]],
                     :“&amp;&amp;“,
                     [:binary,
-                     [:vcall, [:@ident, “b”, [1042, 20]]],
+                     [:var_ref, [:@ident, “b”, [1042, 20]]],
                      :==,
                      [:hash,
                       [:assoclist_from_args,
@@ -5206,7 +5206,7 @@
                      [[:assoc_new,
                        [:@label, “c:“, [1352, 22]],
                        [:@int, “0”, [1352, 25]]]]]],
-                   [:vcall, [:@ident, “r”, [1352, 29]]]],
+                   [:var_ref, [:@ident, “r”, [1352, 29]]]],
                   false]]],
                [:binary,
                 [:call,
@@ -5299,7 +5299,7 @@
                       [:assoc_new,
                        [:@label, “c:“, [1367, 34]],
                        [:@int, “0”, [1367, 37]]]]]],
-                   [:vcall, [:@ident, “r”, [1367, 41]]]],
+                   [:var_ref, [:@ident, “r”, [1367, 41]]]],
                   false]]],
                [:binary,
                 [:call,
@@ -5931,7 +5931,7 @@
              [:in,
               [:hshptn, nil, [], [:var_field, [:@ident, “r”, [1533, 11]]]],
               [[:binary,
-                [:vcall, [:@ident, “r”, [1534, 8]]],
+                [:var_ref, [:@ident, “r”, [1534, 8]]],
                 :==,
                 [:hash,
                  [:assoclist_from_args,
```
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Introduce another semantic value stack for Ripper so that
Ripper can manage both Node and Ruby Object separately.
This rearchitectutre of Ripper solves these issues.
Therefore adding test cases for them.

* [Bug 10436] https://bugs.ruby-lang.org/issues/10436
* [Bug 18988] https://bugs.ruby-lang.org/issues/18988
* [Bug 20055] https://bugs.ruby-lang.org/issues/20055

Checked the differences of `Ripper.sexp` for files under `/test/ruby`
are only on test_pattern_matching.rb.
The differences comes from the differences between
`new_hash_pattern_tail` functions between parser and Ripper.
Ripper `new_hash_pattern_tail` didn’t call `assignable` then
`kw_rest_arg` wasn’t marked as local variable.
This is also fixed by this commit.

```
--- a/./tmp/before/test_pattern_matching.rb
+++ b/./tmp/after/test_pattern_matching.rb
@@ -3607,7 +3607,7 @@
                  [:in,
                   [:hshptn, nil, [], [:var_field, [:@ident, “a”, [984, 13]]]],
                   [[:binary,
-                    [:vcall, [:@ident, “a”, [985, 10]]],
+                    [:var_ref, [:@ident, “a”, [985, 10]]],
                     :==,
                     [:hash, nil]]],
                   nil]]],
@@ -3662,7 +3662,7 @@
                  [:in,
                   [:hshptn, nil, [], [:var_field, [:@ident, “a”, [993, 13]]]],
                   [[:binary,
-                    [:vcall, [:@ident, “a”, [994, 10]]],
+                    [:var_ref, [:@ident, “a”, [994, 10]]],
                     :==,
                     [:hash,
                      [:assoclist_from_args,
@@ -3813,7 +3813,7 @@
                    [:command,
                     [:@ident, “raise”, [1022, 10]],
                     [:args_add_block,
-                     [[:vcall, [:@ident, “b”, [1022, 16]]]],
+                     [[:var_ref, [:@ident, “b”, [1022, 16]]]],
                      false]]],
                   [:else, [[:var_ref, [:@kw, “true”, [1024, 10]]]]]]]],
                nil,
@@ -3876,7 +3876,7 @@
                      [:@int, “0”, [1033, 15]]],
                     :“&amp;&amp;“,
                     [:binary,
-                     [:vcall, [:@ident, “b”, [1033, 20]]],
+                     [:var_ref, [:@ident, “b”, [1033, 20]]],
                      :==,
                      [:hash, nil]]]],
                   nil]]],
@@ -3946,7 +3946,7 @@
                      [:@int, “0”, [1042, 15]]],
                     :“&amp;&amp;“,
                     [:binary,
-                     [:vcall, [:@ident, “b”, [1042, 20]]],
+                     [:var_ref, [:@ident, “b”, [1042, 20]]],
                      :==,
                      [:hash,
                       [:assoclist_from_args,
@@ -5206,7 +5206,7 @@
                      [[:assoc_new,
                        [:@label, “c:“, [1352, 22]],
                        [:@int, “0”, [1352, 25]]]]]],
-                   [:vcall, [:@ident, “r”, [1352, 29]]]],
+                   [:var_ref, [:@ident, “r”, [1352, 29]]]],
                   false]]],
                [:binary,
                 [:call,
@@ -5299,7 +5299,7 @@
                       [:assoc_new,
                        [:@label, “c:“, [1367, 34]],
                        [:@int, “0”, [1367, 37]]]]]],
-                   [:vcall, [:@ident, “r”, [1367, 41]]]],
+                   [:var_ref, [:@ident, “r”, [1367, 41]]]],
                   false]]],
                [:binary,
                 [:call,
@@ -5931,7 +5931,7 @@
              [:in,
               [:hshptn, nil, [], [:var_field, [:@ident, “r”, [1533, 11]]]],
               [[:binary,
-                [:vcall, [:@ident, “r”, [1534, 8]]],
+                [:var_ref, [:@ident, “r”, [1534, 8]]],
                 :==,
                 [:hash,
                  [:assoclist_from_args,
```
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix memory leak for incomplete lambdas</title>
<updated>2023-08-09T18:06:58+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2023-08-09T16:18:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=0b8f15575a440f85ac686f5b0eae8f8b7c2b72e7'/>
<id>0b8f15575a440f85ac686f5b0eae8f8b7c2b72e7</id>
<content type='text'>
[Bug #19836]

The parser does not free the chain of `struct vtable`, which causes
memory leaks.

The following script reproduces this issue:

```
10.times do
  100_000.times do
    Ripper.parse("-&gt; {")
  end

  puts `ps -o rss= -p #{$$}`
end
```
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[Bug #19836]

The parser does not free the chain of `struct vtable`, which causes
memory leaks.

The following script reproduces this issue:

```
10.times do
  100_000.times do
    Ripper.parse("-&gt; {")
  end

  puts `ps -o rss= -p #{$$}`
end
```
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix memory leak in parser for incomplete tokens</title>
<updated>2023-08-09T18:06:58+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2023-08-09T15:03:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=5bc8fceca8d47ed1ef9c603c6531a408de36b60c'/>
<id>5bc8fceca8d47ed1ef9c603c6531a408de36b60c</id>
<content type='text'>
[Bug #19835]

The parser does not free the `tbl` of the `struct vtable` when there are
leftover `lvtbl` in the parser. This causes a memory leak.

The following script reproduces this issue:

```
10.times do
  100_000.times do
    Ripper.parse("class Foo")
  end

  puts `ps -o rss= -p #{$$}`
end
```
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[Bug #19835]

The parser does not free the `tbl` of the `struct vtable` when there are
leftover `lvtbl` in the parser. This causes a memory leak.

The following script reproduces this issue:

```
10.times do
  100_000.times do
    Ripper.parse("class Foo")
  end

  puts `ps -o rss= -p #{$$}`
end
```
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix null pointer access in Ripper#initialize</title>
<updated>2023-07-16T06:41:10+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2023-07-16T06:41:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=5c77402d885799e2465e291bf879dcfbd06ba77c'/>
<id>5c77402d885799e2465e291bf879dcfbd06ba77c</id>
<content type='text'>
In `rb_ruby_ripper_parser_allocate`, `r-&gt;p` is NULL between creating
`self` and `parser_params` assignment.  As GC can happen there, the
typed-data functions for it need to consider the case.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In `rb_ruby_ripper_parser_allocate`, `r-&gt;p` is NULL between creating
`self` and `parser_params` assignment.  As GC can happen there, the
typed-data functions for it need to consider the case.
</pre>
</div>
</content>
</entry>
</feed>
