From 1b9b9609631edd27377b3c8954964146983d763b Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Thu, 15 Feb 2024 23:24:36 +0100 Subject: [PATCH] [ruby/prism] Make location methods thread-safe * Before it could result in NoMethodError if multiple threads were calling location methods: https://gist.github.com/eregon/b78b7f266d7ee0a278a389cfd1782232 https://github.com/ruby/prism/commit/ff762dcccd --- lib/prism/parse_result.rb | 5 +++-- prism/templates/lib/prism/node.rb.erb | 17 ++++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/prism/parse_result.rb b/lib/prism/parse_result.rb index 5b22184ef12572..8ba4e195e6236e 100644 --- a/lib/prism/parse_result.rb +++ b/lib/prism/parse_result.rb @@ -477,8 +477,9 @@ def deconstruct_keys(keys) # A Location object representing the location of this token in the source. def location - return @location if @location.is_a?(Location) - @location = Location.new(source, @location >> 32, @location & 0xFFFFFFFF) + location = @location + return location if location.is_a?(Location) + @location = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Implement the pretty print interface for Token. diff --git a/prism/templates/lib/prism/node.rb.erb b/prism/templates/lib/prism/node.rb.erb index 81a007fcd3d809..a8a02cf72ea1d0 100644 --- a/prism/templates/lib/prism/node.rb.erb +++ b/prism/templates/lib/prism/node.rb.erb @@ -9,8 +9,9 @@ module Prism # A Location instance that represents the location of this node in the # source. def location - return @location if @location.is_a?(Location) - @location = Location.new(source, @location >> 32, @location & 0xFFFFFFFF) + location = @location + return location if location.is_a?(Location) + @location = Location.new(source, location >> 32, location & 0xFFFFFFFF) end def newline? # :nodoc: @@ -196,18 +197,20 @@ module Prism <%- case field -%> <%- when Prism::LocationField -%> def <%= field.name %> - return @<%= field.name %> if @<%= field.name %>.is_a?(Location) - @<%= field.name %> = Location.new(source, @<%= field.name %> >> 32, @<%= field.name %> & 0xFFFFFFFF) + location = @<%= field.name %> + return location if location.is_a?(Location) + @<%= field.name %> = Location.new(source, location >> 32, location & 0xFFFFFFFF) end <%- when Prism::OptionalLocationField -%> def <%= field.name %> - case @<%= field.name %> + location = @<%= field.name %> + case location when nil nil when Location - @<%= field.name %> + location else - @<%= field.name %> = Location.new(source, @<%= field.name %> >> 32, @<%= field.name %> & 0xFFFFFFFF) + @<%= field.name %> = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end <%- else -%>