oracle / truffleruby

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

using "find pattern" matching in a dynamically-defined method results in NPE #3589

Closed flavorjones closed 2 weeks ago

flavorjones commented 3 weeks ago

After seeing an NPE error in Nokogiri's test suite when trying to add tests that use pattern matching, I narrowed down a reproduction to this code:

#! /usr/bin/env ruby

def do_it(name, &block)
  define_method(name, *block)
end

do_it("foo") do
  doc = [1,2,3]
  doc => [*,2,*]
end

which outputs:

<no message> (java.lang.NullPointerException)
        from org.truffleruby.language.locals.WriteLocalVariableNode.cloneUninitialized(WriteLocalVariableNode.java:68)
        from org.truffleruby.core.array.ArrayFindPatternNode.cloneUninitialized(ArrayFindPatternNode.java:93)
        from org.truffleruby.language.control.AndNode.cloneUninitialized(AndNode.java:47)
        from org.truffleruby.language.control.UnlessNode.cloneUninitialized(UnlessNode.java:60)
        from org.truffleruby.language.RubyNode.cloneUninitialized(RubyNode.java:326)
        from org.truffleruby.language.control.SequenceNode.cloneUninitialized(SequenceNode.java:76)
        from org.truffleruby.parser.YARPBlockNodeTranslator.lambda$lambdaCompiler$1(YARPBlockNodeTranslator.java:256)
        from org.truffleruby.core.proc.ProcCallTargets.getCallTargetForLambda(ProcCallTargets.java:72)
        from org.truffleruby.core.module.ModuleNodes$DefineMethodNode.addProc(ModuleNodes.java:1327)
        from org.truffleruby.core.module.ModuleNodes$DefineMethodNode.defineMethodWithProc(ModuleNodes.java:1240)
        from org.truffleruby.core.module.ModuleNodesFactory$DefineMethodNodeFactory$DefineMethodNodeGen.executeAndSpecialize(ModuleNodesFactory.java:6201)
        from org.truffleruby.core.module.ModuleNodesFactory$DefineMethodNodeFactory$DefineMethodNodeGen.execute(ModuleNodesFactory.java:6186)
        from org.truffleruby.language.methods.CallInternalMethodNode.alwaysInlined(CallInternalMethodNode.java:102)
        from org.truffleruby.language.methods.CallInternalMethodNodeGen.executeAndSpecialize(CallInternalMethodNodeGen.java:254)
        from org.truffleruby.language.methods.CallInternalMethodNodeGen.execute(CallInternalMethodNodeGen.java:145)
        from org.truffleruby.language.dispatch.DispatchNode.dispatch(DispatchNode.java:300)
        from org.truffleruby.language.dispatch.DispatchNodeGen.executeAndSpecialize(DispatchNodeGen.java:185)
        from org.truffleruby.language.dispatch.DispatchNodeGen.execute(DispatchNodeGen.java:166)
        from org.truffleruby.language.dispatch.RubyCallNode.doCall(RubyCallNode.java:186)
        from org.truffleruby.language.dispatch.RubyCallNode.execute(RubyCallNode.java:138)
        from org.truffleruby.language.control.SequenceNode.execute(SequenceNode.java:38)
        from org.truffleruby.language.RubyMethodRootNode.execute(RubyMethodRootNode.java:65)
<internal:core> core/main.rb:43:in `define_method'
        from ./foo.rb:4:in `do_it'
        from ./foo.rb:7:in `<main>'

Note that this only seems to happens when using * (the "find pattern") in a block that is passed to define_method.

I'm using truffleruby 24.0.1, like ruby 3.2.2, Oracle GraalVM Native [x86_64-linux].

andrykonchin commented 2 weeks ago

Thank you for reporting! We will take a look soon.

andrykonchin commented 2 weeks ago

Fixed in ca9cfa9cc928c2dd90a04d49a06d887d65a5e774.

flavorjones commented 2 weeks ago

@andrykonchin Thank you! Confirmed this seems fixed when tested with 5603e8bc.