<boc_tothefuture[>
I am trying to understand a bit how java.math.BigDecimal is supposed to work within the ruby ecosystem.
<boc_tothefuture[>
for example, i see it implements coerce but if I do a math operations with it, I get an error.
<boc_tothefuture[>
Like if I do "8 + BigDecimalVariable" I get an exception.
<boc_tothefuture[>
Is there a best practice here, a way to convert BigDecimal to the Ruby version and then go from there? Or really to convert back and forth reliably?
<headius[m]>
you need to use Java's BigDecimal instead of Ruby's?
<boc_tothefuture[>
well.. I am given Java BigDecimal
<boc_tothefuture[>
From the framework
<boc_tothefuture[>
I could convert it to Ruby's if that is the way to go..
<headius[m]>
ah ok... and it isn't converting to Ruby automatically during the call
<boc_tothefuture[>
no, it throws an error essentially saying it can't be casted to that.
<boc_tothefuture[>
Java::JavaLang::ClassCastException (org.jruby.ext.bigdecimal.RubyBigDecimal cannot be cast to java.math.BigDecimal)
<boc_tothefuture[>
but I didn't see a "to_ruby_big_decimal" type method.
<headius[m]>
you can call to_d
<headius[m]>
that is the Ruby coercion method for bigdecimals
<headius[m]>
not common but it is there
<headius[m]>
also need to have done require 'bigdecimal
<enebo[m]>
We have seen interp and JIT do things differently over the years but they tend to just be basic ruby semantics usually in weird corners and it is hard to see how that would happen to make something in ffi do something differently
<enebo[m]>
barring "fell out of the interpreter" and not running half a source file
<headius[m]>
yeah this is literally just -e "system('date')"
<headius[m]>
and it gets to the internal waitpid call
<enebo[m]>
but for that to be true it would be super weird since JIT tends to only kick in after n attempts
<headius[m]>
also reproducible with Process.waitpid spawn 'date'
<enebo[m]>
even the asm part feels weird to me
<enebo[m]>
I guess at some level posix will call down to jnr-ffi which will make it to jffi
<headius[m]>
I could see asm having an effect but why only with compile.mode=OFF? If it is broken it should remain broken
<enebo[m]>
really only two theories have merit: 1) slower execution 2) a bug in interp
<headius[m]>
there's the full output and command line
<enebo[m]>
but what Ruby executes in that call?
<enebo[m]>
something ruby starting up which toggles something
<headius[m]>
oh no
<enebo[m]>
ok so one thing to note here
<headius[m]>
-Xdebug.parser fixes it
<enebo[m]>
yeah I was going to suggest that :)
<headius[m]>
I was getting there from your train of thought
<enebo[m]>
there is no Ruby loaded in that script so for OFF to be effective it would have to do something to earlier Ruby code loaded
<enebo[m]>
I will also say the other thing though...as a test case -e is normally force to compile as the main script
<enebo[m]>
so if you -r something_with_that system it probably would break without compile=off
<enebo[m]>
if it had something to do with those lines
<headius[m]>
yeah this is an interesting wrinkle
<enebo[m]>
but this makes much more sense to me
<enebo[m]>
so something in Ruby loading is working differently with compile=off
<enebo[m]>
That in itself is remarkable
<enebo[m]>
since nothing will compile normally past the main script which has not executed multiple times already
<enebo[m]>
hmm
<enebo[m]>
with default settings do we compile more than the default file/-e?
<headius[m]>
not unless jit fires
<enebo[m]>
ok so let's think through this
<headius[m]>
nothing in prelude should be jitting in this short example
<enebo[m]>
could we errantly execute something 20 times and not notice it is not working during bootstrapping ruby but it always ends up ok in the end because it JITs?
<headius[m]>
there's a little bit of FFI use here but only on Windows and Solaris
<enebo[m]>
and that is the other part of this it takes both to fail
<headius[m]>
I don't see how we wouldn't notice it failing
<enebo[m]>
well we do not see it anywhere but Nix so far
<headius[m]>
what else does debug.parser turn off?
<enebo[m]>
literally everything
<enebo[m]>
all we do is init in Ruby
<enebo[m]>
err initCore I think but we do not load gems or anything in kernel
<enebo[m]>
as you know it exists to debug the parser/lexer so we will never execute any ruby
<headius[m]>
right
<enebo[m]>
how that does it I don't recall
<enebo[m]>
It is super useful as it turns out
<headius[m]>
aha
<headius[m]>
--disable-gems also works
<enebo[m]>
hmm
<enebo[m]>
ok well that removed a thousand lines :)
<headius[m]>
yeah but doesn't help narrow down much 😀
<enebo[m]>
so something in gems or dependency of gems is doing something with ffi and in interp mode it fails?
<enebo[m]>
but that comes back to what would not interp in the first place
<enebo[m]>
and if it failed it would need to keep getting called so a JIT could fix it
<enebo[m]>
headius: can you nuke all the gems?
<headius[m]>
I probably can
<enebo[m]>
one thing gems does is load a lot of crap in a loop
<headius[m]>
I can confirm just disabling did_you_mean does not fix it
<enebo[m]>
and maybe there is something really strange in there that the interp does not do well
<enebo[m]>
but in full it JITs and continues enough where we do not notice not everything is loaded
<headius[m]>
ok weird
<headius[m]>
--disable-gems -rrubygems
<headius[m]>
also is ok
<enebo[m]>
HAHA
<headius[m]>
that should only prevent gem related stuff at boot from loading
<enebo[m]>
so it is not loading any gems but loading rubygems
<headius[m]>
yeah
<headius[m]>
and that is workoi
<headius[m]>
working ok
<enebo[m]>
yeah I wonder if there is a problem loading some gems in that image and we normally JIT something and that "fixes" the bootstrap enough
<headius[m]>
ack nevermind it is intermittent
<headius[m]>
I may be wrong about all this now
<enebo[m]>
with OFF?
<headius[m]>
ok so requiring rubygems does fail
<headius[m]>
just didn't at first
<enebo[m]>
ok
<headius[m]>
I have not gotten --disable-gems alone to fail
<headius[m]>
so there does seem to be a race when it fails
<enebo[m]>
my pet theory has an interesting problem with it. What gem not loaded properly with OFF would then cause something later to stop working because something else finally loaded
<headius[m]>
yeah something that touches FFI and leaves a bad errno somewhere somehow?
<enebo[m]>
hmm we do reset errno at times
<headius[m]>
I bet errno is nonzero before this waitpid call and it isn't cleared
<headius[m]>
I think I can check that
<enebo[m]>
yeah that was what jumped out when you said that
<headius[m]>
could be a libc behavior different on Nix?
<enebo[m]>
but if that is true you should see this behavior potentially in calling many things?
<headius[m]>
not clearing errno in the same places
<headius[m]>
and some gem does an ffi call that leaves an errno set
<headius[m]>
I don't know how to tie this together with compile=off
<enebo[m]>
so it is too bad you cannot build easily since you could remove that errno check
<headius[m]>
oh but compile=off does change how FFI works
<enebo[m]>
I mean printing it before would also be a good check
<headius[m]>
as mentioned earlier
<headius[m]>
so if it started to cause some ffi call booted by rubygems to fail, leave an errno present, and then we don't clear it before this
<headius[m]>
and weird libc just for extra spice
<enebo[m]>
can you repeat how off with ffi is different?
<headius[m]>
errno is 2 before the waitpid call
<headius[m]>
enoent
<enebo[m]>
how does FFI change with compile=off?
<headius[m]>
it uses a generic invoker instead of a bytecode-generated invoker
<headius[m]>
as with the asm property there may be bugs in the generic invoker code never seen because we typically don't run this way
<enebo[m]>
ok that seems likely now
<headius[m]>
I had to do some work on jffi/jnr-ffi to get the non-asm logic passing tests