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

MatchData[x,y] failure #2636

Closed djberg96 closed 2 years ago

djberg96 commented 2 years ago

Truffleruby 22.0.0.2. The following matchdata snippet returns ["X", "113", "8"] for 3.0.x, but Truffleruby bombs:

regex = /(.)(.)(\d+)(\d)/ # => /(.)(.)(\d+)(\d)/
match = regex.match('THX1138.') # => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
p match[2,4] # kerblooey
truffleruby: an internal exception escaped out of the interpreter,
please report it to https://github.com/oracle/truffleruby/issues.

Null receiver values are not supported by libraries. (java.lang.NullPointerException)
    from com.oracle.truffle.api.library.LibraryFactory.dispatch(LibraryFactory.java:528)
    from com.oracle.truffle.api.library.LibraryFactory.create(LibraryFactory.java:295)
    from org.truffleruby.language.objects.ForeignClassNodeGen.executeAndSpecialize(ForeignClassNodeGen.java:104)
    from org.truffleruby.language.objects.ForeignClassNodeGen.execute(ForeignClassNodeGen.java:61)
    from org.truffleruby.language.objects.MetaClassNode.metaClassForeign(MetaClassNode.java:117)
    from org.truffleruby.language.objects.MetaClassNodeGen.executeAndSpecialize(MetaClassNodeGen.java:254)
    from org.truffleruby.language.objects.MetaClassNodeGen.execute(MetaClassNodeGen.java:114)
    from org.truffleruby.language.dispatch.DispatchNode.dispatch(DispatchNode.java:120)
    from org.truffleruby.language.dispatch.RubyCallNode.executeWithArgumentsEvaluated(RubyCallNode.java:140)
    from org.truffleruby.language.dispatch.RubyCallNode.execute(RubyCallNode.java:101)
    from org.truffleruby.language.dispatch.RubyCallNode.executeArguments(RubyCallNode.java:164)
    from org.truffleruby.language.dispatch.RubyCallNode.execute(RubyCallNode.java:94)
    from org.truffleruby.language.locals.WriteLocalVariableNode.execute(WriteLocalVariableNode.java:32)
    from org.truffleruby.language.RubyNode.doExecuteVoid(RubyNode.java:63)
    from org.truffleruby.language.control.SequenceNode.execute(SequenceNode.java:33)
    from org.truffleruby.language.RubyMethodRootNode.execute(RubyMethodRootNode.java:58)
    from org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.executeRootNode(OptimizedCallTarget.java:655)
<internal:core> core/array.rb:611:in `rb_inspect'
    from <internal:core> core/array.rb:611:in `block (2 levels) in inspect'
    from <internal:core> core/enumerable.rb:355:in `each_with_index'
    from <internal:core> core/array.rb:610:in `block in inspect'
    from <internal:core> core/truffle/thread_operations.rb:75:in `detect_recursion'
    from <internal:core> core/array.rb:609:in `inspect'
    from <internal:core> core/post.rb:94:in `block in p'
    from <internal:core> core/post.rb:94:in `each'
    from <internal:core> core/post.rb:94:in `p'
    from (irb):3:in `<top (required)>'
    from /home/dberger/.rbenv/versions/truffleruby-22.0.0.2/lib/mri/irb/workspace.rb:116:in `evaluate'
    from /home/dberger/.rbenv/versions/truffleruby-22.0.0.2/lib/mri/irb/context.rb:450:in `evaluate'
    from /home/dberger/.rbenv/versions/truffleruby-22.0.0.2/lib/mri/irb.rb:567:in `block (2 levels) in eval_input'
    from /home/dberger/.rbenv/versions/truffleruby-22.0.0.2/lib/mri/irb.rb:751:in `signal_status'
    from /home/dberger/.rbenv/versions/truffleruby-22.0.0.2/lib/mri/irb.rb:548:in `block in eval_input'
    from /home/dberger/.rbenv/versions/truffleruby-22.0.0.2/lib/mri/irb/ruby-lex.rb:251:in `block (2 levels) in each_top_level_statement'
    from <internal:core> core/kernel.rb:407:in `loop'
    from /home/dberger/.rbenv/versions/truffleruby-22.0.0.2/lib/mri/irb/ruby-lex.rb:233:in `block in each_top_level_statement'
    from <internal:core> core/throw_catch.rb:36:in `catch'
    from /home/dberger/.rbenv/versions/truffleruby-22.0.0.2/lib/mri/irb/ruby-lex.rb:232:in `each_top_level_statement'
    from /home/dberger/.rbenv/versions/truffleruby-22.0.0.2/lib/mri/irb.rb:547:in `eval_input'
    from /home/dberger/.rbenv/versions/truffleruby-22.0.0.2/lib/mri/irb.rb:481:in `block in run'
    from <internal:core> core/throw_catch.rb:36:in `catch'
    from /home/dberger/.rbenv/versions/truffleruby-22.0.0.2/lib/mri/irb.rb:480:in `run'
    from /home/dberger/.rbenv/versions/truffleruby-22.0.0.2/lib/mri/irb.rb:409:in `start'
    from /home/dberger/.rbenv/versions/truffleruby-22.0.0.2/lib/gems/gems/irb-1.3.5/exe/irb:11:in `<top (required)>'
    from <internal:core> core/kernel.rb:376:in `load'
    from <internal:core> core/kernel.rb:376:in `load'
    from /home/dberger/.rbenv/versions/truffleruby-22.0.0.2/bin/irb:42:in `<main>'
nirvdrum commented 2 years ago

I can take a look at this one.

nirvdrum commented 2 years ago

The issue is our implementation of MatchData#[] with a length argument is attempting to copy too much data. It allocates a result array of length length regardless of how many match values there are. Those extra array entries are all Java null and that's bad for most Ruby operations.

It should be a quick fix. I'll take care of it tomorrow.