oracle / truffleruby

A high performance implementation of the Ruby programming language, built on GraalVM.
https://www.graalvm.org/ruby/
Other
3.02k stars 185 forks source link

Pass the hexapdf test suite #2822

Open eregon opened 1 year ago

eregon commented 1 year ago

This used to work in https://github.com/oracle/truffleruby/issues/1391. Unfortunately there was no CI for hexapdf at the time and it regressed (e.g. #2770). Now hexapdf has a CI: https://github.com/gettalong/hexapdf/pull/199#issuecomment-1375494255

So we should suggest to add truffleruby there, but first of course we need to pass all tests. Some tests fail on latest hexapdf, see https://github.com/eregon/hexapdf/actions/workflows/ci.yml

andrykonchin commented 1 year ago

I've investigated the failed specs and found out that there are basically two issues:

Array#reject

The first issue can be reproduced by modifying an array during iterations through the array with #reject/#reject!

It can be reproduced with the following code:

a = [:a]
counter = 0

a.reject do |el|
  if counter < 1
    a << :b
    counter += 1
  end
  false
end

In CRuby (3.1.3) #reject sees the added element and calls a block for it as well.

On TruffleRuby internal exception is raised.

Floating point numbers

There are several tests that fail because number.round(6).to_s returns a string representation with more than 6 digits after a point:

Test #1

# rbenv local 3.1.3
6.5358983848622465.round(6).to_s # => "6.535898"
5.7639320225002075.round(6).to_s # => "5.763932"
6.535898384862244.round(6).to_s # => "6.535898"

# rbenv local truffleruby-jvm
6.5358983848622465.round(6).to_s => "6.5358979999999995"
5.763932022500207.round(6).to_s => "5.7639320000000005"
6.535898384862244.round(6).to_s => "6.5358979999999995"

Test #2

# rbenv local 3.1.3
1.616.round(6).to_s # => "1.616"

# rbenv local truffleruby-jvm
1.616.round(6).to_s # => "1.6159999999999999"

Test #3

# rbenv local 3.1.3
23.609.round(6).to_s # => "23.609"

# rbenv local truffleruby-jvm
23.609.round(6).to_s # => "23.608999999999998"

Test #4

# rbenv local 3.1.3
3.381966011250105.round(6).to_s # => "3.381966"
8.624771282204213.round(6).to_s # => "8.624771"
7.911127102658033.round(6).to_s # => "7.911127"
7.911127102658032.round(6).to_s # => "7.911127"
8.624771282204211.round(6).to_s # => "8.624771"

# rbenv local truffleruby-jvm
3.381966011250105.round(6).to_s # => "3.3819660000000002"
8.624771282204213.round(6).to_s # => "8.624770999999999"
7.911127102658033.round(6).to_s # => "7.9111270000000005"
7.911127102658032.round(6).to_s # => "7.9111270000000005"
8.624771282204211.round(6).to_s # => "8.624770999999999"
eregon commented 1 year ago

Thanks, it looks like we need fix reject/reject!, and also fix Float#round. Maybe we have an issue similar to https://bugs.ruby-lang.org/issues/19318 re Float#round. @aardvark179 worked on Float#round in https://github.com/oracle/truffleruby/commit/a8d40753701c8a1e9172d66a10f6042bba0143ba but it seems we still have some incompatibility there.

Note that if the to_s differs but the value would be == it wouldn't matter much and that would then be an issue of Float#to_s. But the above seems actual issues of Float#round, e.g.:

$ ruby -e 'p [5.763932022500207.round(6), 5.763932]'
[5.763932, 5.763932, true] # CRuby
[5.7639320000000005, 5.763932, false] # TruffleRuby
andrykonchin commented 1 year ago

Array#reject is fixed in e11a36d6803ea463b349760b00ade14de80db964.