nirvdrum has joined #jruby
nirvdrum has quit [Remote host closed the connection]
travis-ci has joined #jruby
<travis-ci> jruby/jruby (master:552e8a1 by Karol Bucek): The build has errored. https://travis-ci.com/jruby/jruby/builds/218515313 [192 min 37 sec]
travis-ci has left #jruby [#jruby]
nirvdrum has joined #jruby
nirvdrum has quit [Remote host closed the connection]
nirvdrum has joined #jruby
victori has quit [Quit: ZNC 1.8.2 - https://znc.in]
victori has joined #jruby
<headius[m]> enebo so 9.2.16
<headius[m]> We have not had any additional bug reports over the weekend
<headius[m]> enebo: I am trying to do a gem update --system and it seems to run forever generating darkfish doco
<headius[m]> weirdly it shows bash at 100%
<headius[m]> going to try to interrupt with debugger and see what it is doing
<enebo[m]1> yay
<headius[m]> ok maybe it just ran long, seemed to have completed
<headius[m]> I need to confirm
<enebo[m]1> rubygems docs should not run too long?
<enebo[m]1> I mean it is not huge
<enebo[m]1> but yeah 9.2.16 this week is good
<headius[m]> yeah I wouldn't think so... I want to confirm this
<headius[m]> I saw it last week too and chalked it up to environment
<enebo[m]1> headius: kares Something to consider in that PR is whether I killed a deprecated method which someone may expect. None of those deprecations are remotely new and I did not remove very many
<enebo[m]1> We have sooo many deprecated methods but I am a bit shy on being more aggressive due to native extension concerns
<enebo[m]1> So subbu|away wrote a comment like a decade ago which has been bugging me to the point I started to do some block cleanup...SSS FIXME: How is it even possible to "call" a NORMAL block?
<headius[m]> yeah deprecations are tough without having more integration testing across key exts
<headius[m]> I don't think it is possible to call a normal block
<headius[m]> it will always be reified into a proc or lambda if it is callable as a Proc
<headius[m]> or turned into a method in define_method
<enebo[m]1> It is not yet in spec:ruby:fast I found several which make it through call()
<headius[m]> I would like to get stack traces for that because I don't think it should be possible
<enebo[m]1> well so the thing is I have also seen the interesting revert you put in for lambdas doing each_with_index
<enebo[m]1> I feel like we somehow have some stuff twisting around somewhere
<enebo[m]1> but I am looking at figuring out a couple of these mysteries and hopefully things will be simpler
<enebo[m]1> The other thing I am looking at is **kw to a method with no args which is currently broken
<enebo[m]1> which is not even a block issue per se but block pre-processing may complicate this in block case
<headius[m]> revert?
<headius[m]> enebo: what revert do you mean
<enebo[m]1> IRRuntimeHelpers.prepareBlockArgsInternal
<enebo[m]1> 3e3f2f4d43ac6eab27a7ec2b5e4d20880e5fb5fa
<enebo[m]1> was the original landing
<headius[m]> enebo: could consider this for 9.2 but I am not sure if we have had it reported by a user: https://github.com/jruby/jruby/pull/6586
<headius[m]> I ran into it testing out newer RubyGems + Bundler upgrade on JRuby 9.2, and it breaks the `gem` shebang
<headius[m]> it might have always done this and I just noticed it
<enebo[m]1> hmm
<headius[m]> it is definitely broken and this fixes it but there's some small risk since it has not baked
<enebo[m]1> well broken and reported by you. I guess if we do it we should try and poke at it a little bit
<enebo[m]1> At some level I think it would not look great if we do .17 next week but this release will be 2 or 3 fixes so I am not too worried
<enebo[m]1> My larger worry is someone finding something big with .15 about 2 hours after .16 is out :)
<headius[m]> yeah such is life
<headius[m]> kalenp: heads up 9.2.16 coming this week 😃
<kalenp[m]> Thanks for the heads up! I'll see if we can vet the latest snapshots.
<headius[m]> enebo: you know we will have a 9.3.1 within a couple weeks of releasing 9.3 anyway so that might mitigate some deletion risk
<headius[m]> we can just put it back and then fix whatever used it for future
<enebo[m]1> headius: that's true
<enebo[m]1> We could also probably audit top n gems perhaps
<headius[m]> yeah that too
<enebo[m]1> RubyYielder.yield does block.call
<headius[m]> hmmm
<headius[m]> that may have been unintentional
<enebo[m]1> others as well. I am trying yieldValues for that
<enebo[m]1> JavaMethod is doing something where it is doing a .call and ending through Proc.call
<enebo[m]1> at org.jruby.RubyProc$INVOKER$i$call.call(RubyProc$INVOKER$i$call.gen)
<enebo[m]1> at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodZeroOrOneOrNBlock.call(JavaMethod.java:354)
<enebo[m]1> at org.jruby.RubyProc.call(RubyProc.java:291)
<headius[m]> wat
<headius[m]> what line is that on your branch
<headius[m]> slap me some linkage bro
<enebo[m]1> The javaMethod one?
<headius[m]> ohhhh no that is nothing
<headius[m]> that is just the invoker for Proc#call
<headius[m]> the generated stub
<enebo[m]1> at org.jruby.runtime.BlockCallback.call(BlockCallback.java:58)
<enebo[m]1> at org.jruby.runtime.CallBlock.doYield(CallBlock.java:91)
<enebo[m]1> ah yeah CallBlock goes from a yield to a call
<headius[m]> BlockCallback.call is just the name of the impl method for a Java-based block
<headius[m]> it is not the same as Block.call or Proc.call
<enebo[m]1> yeah I am just pointing out the type doing it
<enebo[m]1> oh I see
<enebo[m]1> ok so this calls into ChunkedCallBack in RubyEnumerable
<enebo[m]1> so this ends up from chunk_call which is a callsite
<enebo[m]1> which of course .call on a CallSite is not the same thing as block call
<headius[m]> ahh yeah
<enebo[m]1> final RubyProc categorize = (RubyProc) variables.getInternalVariable("chunk_categorize");
<enebo[m]1> This is the thing which is getting pass in as a Proc but it must be marked as NORMAL
<enebo[m]1> RubyProc.newProc(runtime, block, block.type));
<enebo[m]1> So I am guessing block.type is actually intended to demarcate Lambda vs not lambda here
<enebo[m]1> but since it likely is chunk { |mine| } it will show up as NORMAL
<headius[m]> ahh yeah it should probably be reified as a lambda or proc before being stored
<headius[m]> logically it would have to have been reified to be stored from Ruby, but we have the raw block in Java so we just store that
<enebo[m]1> ok well so far this has been productive...one use was somenoe picking call because yield is IRubyObject and not IRubyObject[]
<enebo[m]1> yieldValues passes so that one maybe is ok using that instead of call
<headius[m]> yeah should be fine
<enebo[m]1> The other was implicitly making a proc internally but retaining the type as normal
<headius[m]> main diff in call and yield is that magic first argument stuff is differenty I think
<enebo[m]1> "yeah should be fine" we shall see but yeah if it ends up not being fine we will just figure out what the difference is
<enebo[m]1> yeah
<enebo[m]1> I am trying to get that one method down to something which is not dual path which should make us abe to bifurcate an IRHelper method into two
<enebo[m]1> One huge issue MRI has and we inherit for a long period of time is they ball up all their logic into multistate tangles of state
<headius[m]> that
<headius[m]> that's for sure
<enebo[m]1> We do this raw pass through of block.type in all Java invokers and a few other places
<enebo[m]1> I feel this should only be LAMBDA or PROC
<headius[m]> yeah probably
<enebo[m]1> Interesting too we are not making LAMBDA as a forced convention for JI
<headius[m]> oh for blocks used as JI impls?
<enebo[m]1> If we are writing a closure to represent last argument I feel we know we have the right arity
<headius[m]> yeah that is an interesting observation
<headius[m]> probably should be lambda based on the semantics of Java methods
<headius[m]> and even Java lambdas
<headius[m]> e.g. return is always local
<enebo[m]1> oh well actually I am just seeing block being setup as an arg for *MethodInvoker
<headius[m]> yeah but that is basically the same as Interface.impl { }
<headius[m]> so it is using a block body as an impl of a Java method, maybe it should be forced to behave like a Ruby lambda?
<headius[m]> I do not know the answer because maybe you are doing something weird and want the non-local return or soft arity
<enebo[m]1> The supplier of values is Java right?
<enebo[m]1> I mean shouldn't we know it will send a particular number of arguments
<enebo[m]1> I guess if we say those will behave as lambdas we will not push nils and crap
<enebo[m]1> or if Java passes a single argument and it happens to be a RubyArray it won't spread?
<headius[m]> yeah java and we just pass through whataver the interface signature is
<headius[m]> Java passing RubyArray 🤣
<headius[m]> I don't want to think about that
<enebo[m]1> HAHA yeah so interface with List will get RubyArray and if our block is n args it will spread
<headius[m]> I think we did do something to java.util.List to allow it to be coerced to array in masgn though so even that might be possible
<headius[m]> yeah
<enebo[m]1> amd I see we have lambda code doing spreads
<headius[m]> so if we set to lambda semantics we would not be at risk of accidentally spreading a list argument
<headius[m]> oh so it would not change that behavior?
<enebo[m]1> Actually maybe lambda never does that
<enebo[m]1> but I would be more concerned that people are depending on proc behavior now that I think about it
<enebo[m]1> but only in the same of 1-artity Java interface method and block having n params
<enebo[m]1> Interesting that we can actually determine that :)
<enebo[m]1> I have another thought though
<enebo[m]1> Block.Type.JAVA
<headius[m]> interesting
<enebo[m]1> the advantage of a new type would be no arity checking but allow spreading
<enebo[m]1> we know we will never get nothing in this case
<headius[m]> hmm yeah I guess another consideration here is if you want lambda semantics there's no way to do it in an inline block
<enebo[m]1> we may have to nil pad unused params because Java never sent them
<headius[m]> you'd have to do &lambda{...}
<enebo[m]1> yeah that's true
<enebo[m]1> I could see someone potentially wanting it both days
<enebo[m]1> err ways
<enebo[m]1> Now that I am thinking about this I think I would prefer lambda by default
<enebo[m]1> but I think we cannot just change this because for sure someone is relying on proc behavior somehow
<headius[m]> probably 😀
<headius[m]> enebo: there's a bug here because it does not provide an encoding for the strings:
<headius[m]> but I do not remember which encoding to get for external encoding of an IO
<enebo[m]1> did someone report against this or did you notice it?
<headius[m]> hmm actually I am not sure what is right behavior
<headius[m]> I am trying to get psych tests green (they never have been)
<headius[m]> some of the failures are due to us passing strings through here as ASCII-8BIT
<headius[m]> if the underlying IO encoding is not compatible it errors
<enebo[m]1> oh well I would almost think IO instance already has logic for what it should be
<enebo[m]1> but you need to also transcode too right?
<headius[m]> well now I am wondering
<headius[m]> this is for OutputStream which just has byte[]
<headius[m]> so we don't know what encoding to use for it
<enebo[m]1> Originally with just seeing the code I half wondered if it was just bytes and should be binary
<headius[m]> this is basically how IOOutputStream short-circuits the dyncall to write
<enebo[m]1> Seems like we know the destined encoding though at the time we make the stream instance from IO itself
<headius[m]> maybe it should just call the normal write directly rather than using this interface which obscures encoding
<enebo[m]1> but using write would definitely make it behave like write was doing it...is that what it should do though since write will do console/int/ext + transcoding
<headius[m]> it is used from here:
<headius[m]> so IOOutputStream gets created with an encoding it should use, like Writer
<headius[m]> but we lose that encoding calling through OutputStream interface
<headius[m]> I am now thinking I should just eliminate this impl
<headius[m]> IOOutputStream should always just call write even if it does it non-dynamically
<headius[m]> so nevermind I will do that so the fast and slow paths work the same
<headius[m]> enebo: env shebang PR is green, fwiw
<headius[m]> I will do this change as a PR also... may be a candidate but again this is just a bug I found on my own
<enebo[m]1> ok
<headius[m]> well my fix works but only resolves one failure
<headius[m]> oh well, progress
<headius[m]> the change just does the same string construction for the fast path as for the slow path, and calls RubyIO.write directly rather than indirecting through that OutputStream impl
<headius[m]> bit more code cleanup in that commit than I should have done, sorry
<enebo[m]1> looks ok to me so long as behaviorally it should be doing all that write does
<enebo[m]1> you have one set of tests which seems to point out some encoding at least
<headius[m]> yeah it should be the same logic as before but now it encodes the string with the right encoding
<enebo[m]1> does it also transcode?
<headius[m]> I also filed a bug for the remaining issue with getOutputStream: https://github.com/jruby/jruby/issues/6588
<headius[m]> that is an open question
<enebo[m]1> I also have wondered whether any specs or mri tests are tagged over this
<headius[m]> the PR just honors the encoding you created the IOOutputStream with
<headius[m]> so it is basically saying an intent to provide bytes encoded as X but we lost that in the old logic
<headius[m]> it is a writer really but writers are lame because they have to be String
<enebo[m]1> lol
<enebo[m]1> This is API
<enebo[m]1> I thought this was some stream_copy thing in Ruby
<headius[m]> I am not sure of any places in JRuby itself that we use this IOOutputStream with a real IO
<headius[m]> usually we only use it when we can't get an actual IO, like in copy_stream with weird inputs
<headius[m]> copy_stream does not use this if the given io is really an IO
<headius[m]> actually it might be using it for anything not a file
<headius[m]> so that could be one place
<enebo[m]1> If it is mostly used by exts then we will not know what they expect but perhaps in case of yaml we do know they expect something other than what we do
<enebo[m]1> If it does bleed into a ruby method then we maybe have a mechanism to test it
<enebo[m]1> I realize now I did not know what it was for but without knowing that I would have assumed encoding would be preserved
<enebo[m]1> in the same way any IO would be
<headius[m]> yeah exactly
<headius[m]> it is just totally broken because one path treats incoming bytes as the requested encoding and the other path treats them as ASCII-8BIT
<headius[m]> unless you have an unencoded IO it just breaks hard
<headius[m]> well it breaks hard if you use high ascii
<headius[m]> which is probably why it hasn't been found until now
<enebo[m]1> yeah
<headius[m]> if you have any thoughts on https://github.com/jruby/jruby/issues/6588 go for it
<headius[m]> I have one other issue for a thing we are missing but won't be implementing it today: there should be a zero-alloc path to writing byte[] into a RubyIO
<headius[m]> given a byte[] range and encoding we should not have to construct even a ByteList to do the write
<headius[m]> but intermediate crud like IO transcoding is written around either RubyString or ByteList (though that logic all just unwraps the bytes eventually too)
<enebo[m]1> yeah
<headius[m]> this could speed up a lot of places we do writes to a known IO
<jswenson[m]> I would be interested in that ^^
<headius[m]> it is all refactoring to add such a path
<headius[m]> just digging another call path through to the places where it actually writes byte[] to the underlying channel
<jswenson[m]> Yeah. I attempted to do something like this through through puma and sinatra until I realized that there was nothing I could do without modifying deeper into jruby.
<headius[m]> yeah there you go, could help a lot of exts run faster
<headius[m]> I started to do it and the path isn't even that deep, except some heavier lifting needed on the transcoding bits
<headius[m]> the actual write goes to byte[] pretty quickly
<headius[m]> so many ways to speed up JRuby that have nothing to do with optimizing Ruby code. 😆
<headius[m]> enebo: I will merge these two PRs then (IOOutputStream and env shebang)
nirvdrum has quit [Ping timeout: 245 seconds]
<enebo[m]1> headius: ok
<headius[m]> jswenson: I don't suppose any of you folks would have time or interest to work on that zero-alloc IO thing
<headius[m]> if your interest is just as a user that's cool... we need it internally anywa
<jswenson[m]> Unfortunately, no time right now. I’ll be following it though if I do get some time.
<headius[m]> ok
nirvdrum has joined #jruby