Skip to content
  • Eileen M. Uchitelle's avatar
    2088a457
    [Bug #17880] Set leaf false on opt_setinlinecache (#4565) · 2088a457
    Eileen M. Uchitelle authored
    This change fixes the bug described in https://bugs.ruby-lang.org/issues/17880
    
    .
    
    Checking `ractor_shareable_p` will cause the method to call back into
    Ruby. Anything calling this method can't be a leaf instruction,
    otherwise it could crash. By adding `attr bool leaf = false` we no
    longer crash because it marks the function as not a leaf.
    
    Here's a simplified reproduction script:
    
    ```ruby
    require "set"
    
    class Id
      attr_reader :db_id
      def initialize(db_id)
        @db_id = db_id
      end
    
      def ==(other)
        other.class == self.class && other.db_id == db_id
      end
      alias_method :eql?, :==
    
      def hash
        10
      end
    
      def <=>(other)
        db_id <=> other.db_id if other.is_a?(self.class)
      end
    end
    
    class Namespace
      IDS = Set[
        Id.new(1).freeze,
        Id.new(2).freeze,
        Id.new(3).freeze,
        Id.new(4).freeze,
      ].freeze
    
      class << self
        def test?(id)
          IDS.include?(id)
        end
      end
    end
    
    p Namespace.test?(Id.new(1))
    p Namespace.test?(Id.new(5))
    ```
    
    Co-authored-by: default avatarAaron Patterson <tenderlove@ruby-lang.org>
    
    Co-authored-by: default avatarAaron Patterson <tenderlove@ruby-lang.org>
    2088a457
    [Bug #17880] Set leaf false on opt_setinlinecache (#4565)
    Eileen M. Uchitelle authored
    This change fixes the bug described in https://bugs.ruby-lang.org/issues/17880
    
    .
    
    Checking `ractor_shareable_p` will cause the method to call back into
    Ruby. Anything calling this method can't be a leaf instruction,
    otherwise it could crash. By adding `attr bool leaf = false` we no
    longer crash because it marks the function as not a leaf.
    
    Here's a simplified reproduction script:
    
    ```ruby
    require "set"
    
    class Id
      attr_reader :db_id
      def initialize(db_id)
        @db_id = db_id
      end
    
      def ==(other)
        other.class == self.class && other.db_id == db_id
      end
      alias_method :eql?, :==
    
      def hash
        10
      end
    
      def <=>(other)
        db_id <=> other.db_id if other.is_a?(self.class)
      end
    end
    
    class Namespace
      IDS = Set[
        Id.new(1).freeze,
        Id.new(2).freeze,
        Id.new(3).freeze,
        Id.new(4).freeze,
      ].freeze
    
      class << self
        def test?(id)
          IDS.include?(id)
        end
      end
    end
    
    p Namespace.test?(Id.new(1))
    p Namespace.test?(Id.new(5))
    ```
    
    Co-authored-by: default avatarAaron Patterson <tenderlove@ruby-lang.org>
    
    Co-authored-by: default avatarAaron Patterson <tenderlove@ruby-lang.org>
Loading