From 3ec49b9870d8c26d552bd6ae7aa6a0f452daec25 Mon Sep 17 00:00:00 2001 From: Aiden Fox Ivey Date: Mon, 6 Oct 2025 14:11:32 -0400 Subject: [PATCH 01/19] ZJIT: Make documentation command target ZJIT specifically --- doc/zjit.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/zjit.md b/doc/zjit.md index 65151051c8ea98..d0e66dfe85645d 100644 --- a/doc/zjit.md +++ b/doc/zjit.md @@ -26,7 +26,10 @@ in a way that can be easily shared with other team members. ## Documentation -You can generate and open the source level documentation in your browser using `cargo doc --open --document-private-items`. +You can generate and open the source level documentation in your browser using: +``` +cargo doc --document-private-items -p zjit --open +``` ## Testing From 5f4877ab9e2892e294d3f07b13c8e4ec1bb4d70a Mon Sep 17 00:00:00 2001 From: Aiden Fox Ivey Date: Mon, 6 Oct 2025 14:12:18 -0400 Subject: [PATCH 02/19] ZJIT: Simplify cargo install commands for nextest and insta --- doc/zjit.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/zjit.md b/doc/zjit.md index d0e66dfe85645d..86a27d71194d09 100644 --- a/doc/zjit.md +++ b/doc/zjit.md @@ -34,8 +34,11 @@ cargo doc --document-private-items -p zjit --open ## Testing Make sure you have a `--enable-zjit=dev` build, and install the following tools: -- `brew install cargo-nextest` - Required for running tests -- `cargo install cargo-insta` - Required for updating snapshots +``` +cargo install cargo-nextest +cargo install cargo-insta +``` +`cargo-nextest` is required for running tests, whereas `cargo-insta` is used for updating snapshots. ### make zjit-check From 11f625f9f7ce61a3ddac98e99776350439b9d4fe Mon Sep 17 00:00:00 2001 From: Aiden Fox Ivey Date: Mon, 6 Oct 2025 15:42:07 -0400 Subject: [PATCH 03/19] ZJIT: Format the term-definition table * Using extra whitespace should not harm rendering it on github.com or docs.ruby-lang.org, but will make it easier for those in a text editor to read it. --- doc/zjit.md | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/doc/zjit.md b/doc/zjit.md index 86a27d71194d09..b7a3e1827c1e79 100644 --- a/doc/zjit.md +++ b/doc/zjit.md @@ -179,26 +179,26 @@ This glossary contains terms that are helpful for understanding ZJIT. Please note that some terms may appear in CRuby internals too but with different meanings. -| Term | Definition | -| --- | -----------| -| HIR | High-level Intermediate Representation. High-level (Ruby semantics) graph representation in static single-assignment (SSA) form | -| LIR | Low-level Intermediate Representation. Low-level IR used in the backend for assembly generation | -| SSA | Static Single Assignment. A form where each variable is assigned exactly once | -| `opnd` | Operand. An operand to an IR instruction (can be register, memory, immediate, etc.) | -| `dst` | Destination. The output operand of an instruction where the result is stored | -| VReg | Virtual Register. A virtual register that gets lowered to physical register or memory | -| `insn_id` | Instruction ID. An index of an instruction in a function | -| `block_id` | The index of a basic block, which effectively acts like a pointer | -| `branch` | Control flow edge between basic blocks in the compiled code | -| `cb` | Code Block. Memory region for generated machine code | -| `entry` | The starting address of compiled code for an ISEQ | -| Patch Point | Location in generated code that can be modified later in case assumptions get invalidated | -| Frame State | Captured state of the Ruby stack frame at a specific point for deoptimization | -| Guard | A run-time check that ensures assumptions are still valid | -| `invariant` | An assumption that JIT code relies on, requiring invalidation if broken | -| Deopt | Deoptimization. Process of falling back from JIT code to interpreter | -| Side Exit | Exit from JIT code back to interpreter | -| Type Lattice | Hierarchy of types used for type inference and optimization | -| Constant Folding | Optimization that evaluates constant expressions at compile time | -| RSP | x86-64 stack pointer register used for native stack operations | -| Register Spilling | Process of moving register values to memory when running out of physical registers | +| Term | Definition | +| ----------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| HIR | High-level Intermediate Representation. High-level (Ruby semantics) graph representation in static single-assignment (SSA) form | +| LIR | Low-level Intermediate Representation. Low-level IR used in the backend for assembly generation | +| SSA | Static Single Assignment. A form where each variable is assigned exactly once | +| `opnd` | Operand. An operand to an IR instruction (can be register, memory, immediate, etc.) | +| `dst` | Destination. The output operand of an instruction where the result is stored | +| VReg | Virtual Register. A virtual register that gets lowered to physical register or memory | +| `insn_id` | Instruction ID. An index of an instruction in a function | +| `block_id` | The index of a basic block, which effectively acts like a pointer | +| `branch` | Control flow edge between basic blocks in the compiled code | +| `cb` | Code Block. Memory region for generated machine code | +| `entry` | The starting address of compiled code for an ISEQ | +| Patch Point | Location in generated code that can be modified later in case assumptions get invalidated | +| Frame State | Captured state of the Ruby stack frame at a specific point for deoptimization | +| Guard | A run-time check that ensures assumptions are still valid | +| `invariant` | An assumption that JIT code relies on, requiring invalidation if broken | +| Deopt | Deoptimization. Process of falling back from JIT code to interpreter | +| Side Exit | Exit from JIT code back to interpreter | +| Type Lattice | Hierarchy of types used for type inference and optimization | +| Constant Folding | Optimization that evaluates constant expressions at compile time | +| RSP | x86-64 stack pointer register used for native stack operations | +| Register Spilling | Process of moving register values to memory when running out of physical registers | From a3d1752c20c477816b835fcec24e0d6ad0d773b5 Mon Sep 17 00:00:00 2001 From: Aiden Fox Ivey Date: Mon, 6 Oct 2025 15:44:09 -0400 Subject: [PATCH 04/19] ZJIT: Escape $HOME and format multiline configure command --- doc/zjit.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/zjit.md b/doc/zjit.md index b7a3e1827c1e79..6a8dbd629a7c81 100644 --- a/doc/zjit.md +++ b/doc/zjit.md @@ -5,7 +5,13 @@ To build ZJIT on macOS: ``` ./autogen.sh -./configure --enable-zjit=dev --prefix=$HOME/.rubies/ruby-zjit --disable-install-doc --with-opt-dir="$(brew --prefix openssl):$(brew --prefix readline):$(brew --prefix libyaml)" + +./configure \ + --enable-zjit=dev \ + --prefix="$HOME"/.rubies/ruby-zjit \ + --disable-install-doc \ + --with-opt-dir="$(brew --prefix openssl):$(brew --prefix readline):$(brew --prefix libyaml)" + make -j miniruby ``` From 4a7ca3d836a2bbbd2e3c6cbaf3002ffa5a2b0078 Mon Sep 17 00:00:00 2001 From: Aiden Fox Ivey Date: Mon, 6 Oct 2025 15:52:52 -0400 Subject: [PATCH 05/19] ZJIT: Reformat and add highlighting to ZJIT documentation * Add bash above code blocks that can use highlighting * Move Useful dev commands below documentation, testing, and building * Rewrite testing documentation to better explain what each form of test does --- doc/zjit.md | 108 +++++++++++++++++++++++++--------------------------- 1 file changed, 51 insertions(+), 57 deletions(-) diff --git a/doc/zjit.md b/doc/zjit.md index 6a8dbd629a7c81..c0378031b24bd2 100644 --- a/doc/zjit.md +++ b/doc/zjit.md @@ -3,7 +3,8 @@ ## Build Instructions To build ZJIT on macOS: -``` + +```bash ./autogen.sh ./configure \ @@ -15,62 +16,48 @@ To build ZJIT on macOS: make -j miniruby ``` -## Useful dev commands - -To view YARV output for code snippets: -``` -./miniruby --dump=insns -e0 -``` - -To run code snippets with ZJIT: -``` -./miniruby --zjit -e0 -``` - -You can also try https://www.rubyexplorer.xyz/ to view Ruby YARV disasm output with syntax highlighting -in a way that can be easily shared with other team members. - ## Documentation You can generate and open the source level documentation in your browser using: -``` + +```bash cargo doc --document-private-items -p zjit --open ``` ## Testing -Make sure you have a `--enable-zjit=dev` build, and install the following tools: -``` -cargo install cargo-nextest -cargo install cargo-insta -``` -`cargo-nextest` is required for running tests, whereas `cargo-insta` is used for updating snapshots. +Note that tests link against CRuby, so directly calling `cargo test`, or `cargo nextest` should not build. All tests are instead accessed through `make`. -### make zjit-check +### Setup -This command runs all ZJIT tests: `make zjit-test` and `test/ruby/test_zjit.rb`. +First, ensure you have `cargo` installed. If you do not already have it, you can use [rustup.rs](https://rustup.rs/). -``` -make zjit-check +Make sure to add `--enable-zjit=dev` when you run `configure`, then install the following tools: + +```bash +cargo install cargo-nextest +cargo install cargo-insta ``` -### make zjit-test +`cargo-insta` is used for updating snapshots. `cargo-nextest` runs each test in its own process, which is valuable since CRuby only supports booting once per process, and most APIs are not thread safe. -This command runs Rust unit tests using `insta` for snapshot testing. +### Running unit tests -``` +For testing functionality within ZJIT, use: + +```bash make zjit-test ``` You can also run a single test case by specifying the function name: -``` +```bash make zjit-test ZJIT_TESTS=test_putobject ``` #### Snapshot Testing -ZJIT uses [insta](https://insta.rs/) for snapshot testing. When tests fail due to snapshot mismatches, pending snapshots are created. The test command will notify you if there are pending snapshots: +ZJIT uses [insta](https://insta.rs/) for snapshot testing within unit tests. When tests fail due to snapshot mismatches, pending snapshots are created. The test command will notify you if there are pending snapshots: ``` Pending snapshots found. Accept with: make zjit-test-update @@ -78,50 +65,40 @@ Pending snapshots found. Accept with: make zjit-test-update To update/accept all the snapshot changes: -``` +```bash make zjit-test-update ``` You can also review snapshot changes interactively one by one: -``` +```bash cd zjit && cargo insta review ``` Test changes will be reviewed alongside code changes. -
- -Setting up zjit-test - -ZJIT uses `cargo-nextest` for Rust unit tests instead of `cargo test`. -`cargo-nextest` runs each test in its own process, which is valuable since -CRuby only supports booting once per process, and most APIs are not thread -safe. Use `brew install cargo-nextest` to install it on macOS, otherwise, refer -to for installation -instructions. - -Since it uses Cargo, you'll also need a `configure --enable-zjit=dev ...` build -for `make zjit-test`. Since the tests need to link against CRuby, directly -calling `cargo test`, or `cargo nextest` likely won't build. Make sure to -use `make`. - -
- -### test/ruby/test\_zjit.rb +### Running integration tests This command runs Ruby execution tests. -``` +```bash make test-all TESTS="test/ruby/test_zjit.rb" ``` You can also run a single test case by matching the method name: -``` +```bash make test-all TESTS="test/ruby/test_zjit.rb -n TestZJIT#test_putobject" ``` +### Running all tests + +Runs both `make zjit-test` and `test/ruby/test_zjit.rb`: + +```bash +make zjit-check +``` + ## Statistics Collection ZJIT provides detailed statistics about JIT compilation and execution behavior. @@ -173,12 +150,29 @@ Through [Stackprof](https://github.com/tmm1/stackprof), detailed information abo ./miniruby --zjit-trace-exits script.rb ``` -A file called `zjit_exit_locations.dump` will be created in the same directory as `script.rb`. Viewing the side exited methods can be done with Stackprof: +A file called `zjit_exit_locations{timestamp}.dump` will be created in the same directory as `script.rb`. Viewing the side exited methods can be done with Stackprof: + +```bash +stackprof path/to/zjit_exit_locations{timestamp}.dump +``` + +## Useful dev commands + +To view YARV output for code snippets: + +```bash +./miniruby --dump=insns -e0 +``` + +To run code snippets with ZJIT: ```bash -stackprof path/to/zjit_exit_locations.dump +./miniruby --zjit -e0 ``` +You can also try https://www.rubyexplorer.xyz/ to view Ruby YARV disasm output with syntax highlighting +in a way that can be easily shared with other team members. + ## ZJIT Glossary This glossary contains terms that are helpful for understanding ZJIT. From 3ba5cfd1cb77b61b2b1ad1d03271bc1fe7b71969 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 6 Oct 2025 13:25:00 -0700 Subject: [PATCH 06/19] Add a workflow to sync default gems (#14749) --- ...default_gems.yml => default_gems_list.yml} | 2 +- .github/workflows/sync_default_gems.yml | 67 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) rename .github/workflows/{default_gems.yml => default_gems_list.yml} (99%) create mode 100644 .github/workflows/sync_default_gems.yml diff --git a/.github/workflows/default_gems.yml b/.github/workflows/default_gems_list.yml similarity index 99% rename from .github/workflows/default_gems.yml rename to .github/workflows/default_gems_list.yml index 7935afc44a333c..37a2af03c7b980 100644 --- a/.github/workflows/default_gems.yml +++ b/.github/workflows/default_gems_list.yml @@ -9,7 +9,7 @@ permissions: contents: read jobs: - update_default_gems: + update_default_gems_list: name: Update default gems list permissions: diff --git a/.github/workflows/sync_default_gems.yml b/.github/workflows/sync_default_gems.yml new file mode 100644 index 00000000000000..f1ae1f7d51bdb8 --- /dev/null +++ b/.github/workflows/sync_default_gems.yml @@ -0,0 +1,67 @@ +name: Sync default gems +on: + # Main use of this workflow. Called by default gem repositories by API. + repository_dispatch: + types: + - sync_default_gems + + # Web UI dispatch for testing and manual operations. + workflow_dispatch: + inputs: + gem: + required: true + description: 'Name of the gem to be synchronized' + type: string + before: + required: true + description: 'Gem commit SHA before sync' + type: string + after: + required: true + description: 'Gem commit SHA after sync' + type: string + +jobs: + sync_default_gems: + name: Update default gems list + + permissions: + contents: write # for Git to git push + + runs-on: ubuntu-latest + + if: ${{ github.repository == 'ruby/ruby' }} + + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + name: Check out ruby/ruby + with: + token: ${{ (github.repository == 'ruby/ruby' && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} + + - name: Run tool/sync_default_gems.rb + run: ruby tool/sync_default_gems.rb "${gem_name}" "${gem_before}..${gem_after}" + env: + gem_name: ${{ github.event.client_payload.gem || github.event.inputs.gem }} + gem_before: ${{ github.event.client_payload.before || github.event.inputs.before }} + gem_after: ${{ github.event.client_payload.after || github.event.inputs.after }} + + - name: Check diffs + id: diff + run: | + git diff --color --no-ext-diff --ignore-submodules --exit-code || + echo update=true >> $GITHUB_OUTPUT + + - name: Push + run: | + git pull --ff-only origin ${GITHUB_REF#refs/heads/} + git push origin ${GITHUB_REF#refs/heads/} + env: + EMAIL: svn-admin@ruby-lang.org + GIT_AUTHOR_NAME: git + GIT_COMMITTER_NAME: git + if: ${{ steps.diff.outputs.update }} + + - uses: ./.github/actions/slack + with: + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + if: ${{ failure() }} From c9b726028cfe9f18bf5d4e5bb4c64d9a0b481448 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 6 Oct 2025 13:43:25 -0700 Subject: [PATCH 07/19] sync_default_gems.yml: Remove an unmatched paren --- .github/workflows/sync_default_gems.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync_default_gems.yml b/.github/workflows/sync_default_gems.yml index f1ae1f7d51bdb8..324c5d27a5ee88 100644 --- a/.github/workflows/sync_default_gems.yml +++ b/.github/workflows/sync_default_gems.yml @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 name: Check out ruby/ruby with: - token: ${{ (github.repository == 'ruby/ruby' && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} + token: ${{ github.repository == 'ruby/ruby' && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} - name: Run tool/sync_default_gems.rb run: ruby tool/sync_default_gems.rb "${gem_name}" "${gem_before}..${gem_after}" From 43eb41ec949229eaa1b8da0b1ac7beebe247186b Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 6 Oct 2025 13:46:00 -0700 Subject: [PATCH 08/19] sync_default_gems.yml: Fix a wrong job name --- .github/workflows/sync_default_gems.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync_default_gems.yml b/.github/workflows/sync_default_gems.yml index 324c5d27a5ee88..c74f73ad589c5b 100644 --- a/.github/workflows/sync_default_gems.yml +++ b/.github/workflows/sync_default_gems.yml @@ -23,7 +23,7 @@ on: jobs: sync_default_gems: - name: Update default gems list + name: Sync default gems permissions: contents: write # for Git to git push From 03030bf112db6346b4055adb098bc93b95b6321a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Barri=C3=A9?= Date: Mon, 6 Oct 2025 16:37:29 +0200 Subject: [PATCH 09/19] Remove unused variable warning $ make test/ruby/test_thread.rb RUBYOPT=-w >/dev/null test/ruby/test_thread.rb:1595: warning: assigned but unused variable - bug21127 --- test/ruby/test_thread.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb index 01a1e51025181c..c08d41cb863a2c 100644 --- a/test/ruby/test_thread.rb +++ b/test/ruby/test_thread.rb @@ -1592,7 +1592,6 @@ def frame_for_deadlock_test_2 # [Bug #21342] def test_unlock_locked_mutex_with_collected_fiber - bug21127 = '[ruby-core:120930] [Bug #21127]' assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}") begin; 5.times do From 57ea1c0be116db77834b9bd9850f3ee81d495247 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 6 Oct 2025 13:53:21 -0700 Subject: [PATCH 10/19] sync_default_gems.yml: Detect past renames --- .github/workflows/sync_default_gems.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/sync_default_gems.yml b/.github/workflows/sync_default_gems.yml index c74f73ad589c5b..d3aab34edb9644 100644 --- a/.github/workflows/sync_default_gems.yml +++ b/.github/workflows/sync_default_gems.yml @@ -36,8 +36,12 @@ jobs: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 name: Check out ruby/ruby with: + fetch-depth: 0 # Fetch all history to recognize past renames token: ${{ github.repository == 'ruby/ruby' && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} + - name: Increase rename limit + run: git config merge.renameLimit 999999 + - name: Run tool/sync_default_gems.rb run: ruby tool/sync_default_gems.rb "${gem_name}" "${gem_before}..${gem_after}" env: @@ -45,12 +49,6 @@ jobs: gem_before: ${{ github.event.client_payload.before || github.event.inputs.before }} gem_after: ${{ github.event.client_payload.after || github.event.inputs.after }} - - name: Check diffs - id: diff - run: | - git diff --color --no-ext-diff --ignore-submodules --exit-code || - echo update=true >> $GITHUB_OUTPUT - - name: Push run: | git pull --ff-only origin ${GITHUB_REF#refs/heads/} @@ -59,7 +57,6 @@ jobs: EMAIL: svn-admin@ruby-lang.org GIT_AUTHOR_NAME: git GIT_COMMITTER_NAME: git - if: ${{ steps.diff.outputs.update }} - uses: ./.github/actions/slack with: From 7f6e9a0b1beec5d6d50d50a15b95e2360e2ce493 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 6 Oct 2025 14:01:25 -0700 Subject: [PATCH 11/19] sync_default_gems.yml: Avoid fetching tags/branches --- .github/workflows/sync_default_gems.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync_default_gems.yml b/.github/workflows/sync_default_gems.yml index d3aab34edb9644..7528576eaf1213 100644 --- a/.github/workflows/sync_default_gems.yml +++ b/.github/workflows/sync_default_gems.yml @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 name: Check out ruby/ruby with: - fetch-depth: 0 # Fetch all history to recognize past renames + fetch-depth: 999999 # Fetch all history to follow past renames. Not using 0 to avoid fetching tags/branches. token: ${{ github.repository == 'ruby/ruby' && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} - name: Increase rename limit From 6c1b5887149e731906e003af6fc8bfc1bc112c28 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 6 Oct 2025 14:03:48 -0700 Subject: [PATCH 12/19] sync_default_gems.yml: Move the git config to the script --- .github/workflows/sync_default_gems.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/sync_default_gems.yml b/.github/workflows/sync_default_gems.yml index 7528576eaf1213..301a59e3968e8a 100644 --- a/.github/workflows/sync_default_gems.yml +++ b/.github/workflows/sync_default_gems.yml @@ -48,15 +48,14 @@ jobs: gem_name: ${{ github.event.client_payload.gem || github.event.inputs.gem }} gem_before: ${{ github.event.client_payload.before || github.event.inputs.before }} gem_after: ${{ github.event.client_payload.after || github.event.inputs.after }} + EMAIL: svn-admin@ruby-lang.org + GIT_AUTHOR_NAME: git + GIT_COMMITTER_NAME: git - name: Push run: | git pull --ff-only origin ${GITHUB_REF#refs/heads/} git push origin ${GITHUB_REF#refs/heads/} - env: - EMAIL: svn-admin@ruby-lang.org - GIT_AUTHOR_NAME: git - GIT_COMMITTER_NAME: git - uses: ./.github/actions/slack with: From bc8732b6c81c761a6ed693effb0f497f39f43ea3 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 6 Oct 2025 14:08:03 -0700 Subject: [PATCH 13/19] sync_default_gems.yml: Attempt push only if needed --- .github/workflows/sync_default_gems.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sync_default_gems.yml b/.github/workflows/sync_default_gems.yml index 301a59e3968e8a..211d75dcf79de5 100644 --- a/.github/workflows/sync_default_gems.yml +++ b/.github/workflows/sync_default_gems.yml @@ -43,7 +43,14 @@ jobs: run: git config merge.renameLimit 999999 - name: Run tool/sync_default_gems.rb - run: ruby tool/sync_default_gems.rb "${gem_name}" "${gem_before}..${gem_after}" + id: sync + run: | + ruby_before=$(git rev-parse HEAD) + set -x + ruby tool/sync_default_gems.rb "${gem_name}" "${gem_before}..${gem_after}" + if [[ "$(git rev-parse HEAD)" != "$ruby_before" ]]; then + echo update=true >> $GITHUB_OUTPUT + fi env: gem_name: ${{ github.event.client_payload.gem || github.event.inputs.gem }} gem_before: ${{ github.event.client_payload.before || github.event.inputs.before }} @@ -56,6 +63,7 @@ jobs: run: | git pull --ff-only origin ${GITHUB_REF#refs/heads/} git push origin ${GITHUB_REF#refs/heads/} + if: ${{ steps.sync.outputs.update }} - uses: ./.github/actions/slack with: From 2a484ce3c313fa4cf050e599220d9a870c901f29 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Sun, 5 Oct 2025 17:29:30 -0400 Subject: [PATCH 14/19] [ruby/prism] Free current_block_exits for the program We need to free the current_block_exits in parse_program when we're done with it to prevent memory leaks. This fixes the following memory leak detected when running Ruby using `RUBY_FREE_AT_EXIT=1 ruby -nc -e "break"`: Direct leak of 32 byte(s) in 1 object(s) allocated from: #0 0x5bd3c5bc66c8 in realloc (miniruby+0x616c8) (BuildId: https://github.com/ruby/prism/commit/ba6a96e5a060) #1 0x5bd3c5f91fd9 in pm_node_list_grow prism/templates/src/node.c.erb:35:40 #2 0x5bd3c5f91e9d in pm_node_list_append prism/templates/src/node.c.erb:48:9 #3 0x5bd3c6001fa0 in parse_block_exit prism/prism.c:15788:17 #4 0x5bd3c5fee155 in parse_expression_prefix prism/prism.c:19221:50 #5 0x5bd3c5fe9970 in parse_expression prism/prism.c:22235:23 #6 0x5bd3c5fe0586 in parse_statements prism/prism.c:13976:27 #7 0x5bd3c5fd6792 in parse_program prism/prism.c:22508:40 https://github.com/ruby/prism/commit/fdf9b8d24a --- prism/prism.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/prism/prism.c b/prism/prism.c index 22ac19b5e469fe..f85a69332ed95c 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -22524,9 +22524,10 @@ parse_program(pm_parser_t *parser) { statements = wrap_statements(parser, statements); } else { flush_block_exits(parser, previous_block_exits); - pm_node_list_free(¤t_block_exits); } + pm_node_list_free(¤t_block_exits); + // If this is an empty file, then we're still going to parse all of the // statements in order to gather up all of the comments and such. Here we'll // correct the location information. From dad064a0ea823222f729367b501e7d6e5ad0e505 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 6 Oct 2025 15:01:19 -0700 Subject: [PATCH 15/19] [ruby/erb] Version 5.0.3 https://github.com/ruby/erb/commit/ddfc1ba57e --- lib/erb/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/erb/version.rb b/lib/erb/version.rb index 7d0b384f71c741..521e77ce4aac5b 100644 --- a/lib/erb/version.rb +++ b/lib/erb/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class ERB # The string \ERB version. - VERSION = '5.0.2' + VERSION = '5.0.3' end From 854491fe998d531006d2f2447252975d5f764f11 Mon Sep 17 00:00:00 2001 From: git Date: Mon, 6 Oct 2025 22:05:03 +0000 Subject: [PATCH 16/19] Update default gems list at dad064a0ea823222f729367b501e7d [ci skip] --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 6c39404721c887..dafce164998b18 100644 --- a/NEWS.md +++ b/NEWS.md @@ -182,7 +182,7 @@ The following default gems are updated. * RubyGems 3.8.0.dev * bundler 2.8.0.dev -* erb 5.0.2 +* erb 5.0.3 * etc 1.4.6 * fcntl 1.3.0 * io-console 0.8.1 From 8c0fc05832111055c5f01014c0b831fc9f97e4f3 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 6 Oct 2025 16:17:45 -0700 Subject: [PATCH 17/19] sync_default_gems.yml: Remove unused repository_dispatch We actually use the workflow-level dispatch from API as well --- .github/workflows/sync_default_gems.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/sync_default_gems.yml b/.github/workflows/sync_default_gems.yml index 211d75dcf79de5..edbb4399d4ec70 100644 --- a/.github/workflows/sync_default_gems.yml +++ b/.github/workflows/sync_default_gems.yml @@ -1,11 +1,5 @@ name: Sync default gems on: - # Main use of this workflow. Called by default gem repositories by API. - repository_dispatch: - types: - - sync_default_gems - - # Web UI dispatch for testing and manual operations. workflow_dispatch: inputs: gem: From b1e672bb4840d50b90031046d92f787d060a358a Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 6 Oct 2025 16:18:26 -0700 Subject: [PATCH 18/19] sync_default_gems.yml: Remove client_payload references Now that repository_dispatch is gone, we don't need them either. --- .github/workflows/sync_default_gems.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sync_default_gems.yml b/.github/workflows/sync_default_gems.yml index edbb4399d4ec70..bd5b30b8613898 100644 --- a/.github/workflows/sync_default_gems.yml +++ b/.github/workflows/sync_default_gems.yml @@ -46,9 +46,9 @@ jobs: echo update=true >> $GITHUB_OUTPUT fi env: - gem_name: ${{ github.event.client_payload.gem || github.event.inputs.gem }} - gem_before: ${{ github.event.client_payload.before || github.event.inputs.before }} - gem_after: ${{ github.event.client_payload.after || github.event.inputs.after }} + gem_name: ${{ github.event.inputs.gem }} + gem_before: ${{ github.event.inputs.before }} + gem_after: ${{ github.event.inputs.after }} EMAIL: svn-admin@ruby-lang.org GIT_AUTHOR_NAME: git GIT_COMMITTER_NAME: git From e3d4cb5de52332b475635949f48b5cc5620a9a5e Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 6 Oct 2025 17:41:55 -0700 Subject: [PATCH 19/19] Sync Prism (#14751) to https://github.com/ruby/prism/commit/c89ca2af12ba20b4fd2c5ff43ebe25da1d81d8db --- test/prism/fixtures/string_concatination_frozen_false.txt | 5 +++++ test/prism/fixtures/string_concatination_frozen_true.txt | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 test/prism/fixtures/string_concatination_frozen_false.txt create mode 100644 test/prism/fixtures/string_concatination_frozen_true.txt diff --git a/test/prism/fixtures/string_concatination_frozen_false.txt b/test/prism/fixtures/string_concatination_frozen_false.txt new file mode 100644 index 00000000000000..abe9301408e352 --- /dev/null +++ b/test/prism/fixtures/string_concatination_frozen_false.txt @@ -0,0 +1,5 @@ +# frozen_string_literal: false + +'foo' 'bar' + +'foo' 'bar' "baz#{bat}" diff --git a/test/prism/fixtures/string_concatination_frozen_true.txt b/test/prism/fixtures/string_concatination_frozen_true.txt new file mode 100644 index 00000000000000..829777f0a70259 --- /dev/null +++ b/test/prism/fixtures/string_concatination_frozen_true.txt @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +'foo' 'bar' + +'foo' 'bar' "baz#{bat}"