-
-
Notifications
You must be signed in to change notification settings - Fork 925
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix some issues with Fiddle #4511
Conversation
I just made it equal to RUBY_PLATFORM, which will always be Java
Behaves more like MRI
Pointer#free= should accept an Integer or Pointer Pointer#free should return a new instance of Fiddle::Function Pointer#free should return nil if free is zero
Behaves more like MRI. Previously passing something in that was neither an FFI::Pointer nor an Integer would cause undesirable results.
The difference is, without passing `len` in to the function: 1. to_s returns a null-terminated string 2. to_str returns a string of as many bytes a the pointer's size
Some hidden, undocumented "features" of Pointer#[]= include: 1. Passing a Pointer instead of a String, whereby data is copied from the passed-in pointer 2. Passing an Integer instead of a string, using the integer as a memory address to copy from
Thanks for this! Our Fiddle implementation has not had a lot of love since the initial implementation, so any help you can provide here is quite welcome! We've decided to up the priority on this and get it into 9.1.8.0 rather than waiting for 9.2. If you can help fix the remaining issues after 9.1.8.0 that would be a great help also. I'll take a quick look at them today. |
This is a re-merge on a separate branch due to Wnidows breakage caused by the original fixes.
This is a re-commit on a new branch because of Windows breakage caused by jruby#4511.
Ok, so these looked nice on Linux but it appears to have broken something on Windows. I've created #4518 containing your changes and my commit to enable Fiddle tests. We can iterate together on getting things working right based on https://github.com/headius/jruby/tree/fiddle-fixes. |
After having some trouble getting Mittsu working in JRuby, I thought I'd have a look at JRuby's Fiddle implementation. There are quite a number of inconsistencies and straight-up broken bits, so I thought I'd take a crack at some of them. This is not a conclusive fix or anything, but hopefully I can get it working enough for most.
Here are the list of the bigger changes:
TYPE_PTRDIFF_T
was not defined. This has been voiced before (IllegalArgumentException when using Fiddle to wrap C libraries #3477). I had a look, and other types such asTYPE_SIZE_T
, etc. were also missing. I've added all the missing types, basing their byte sizes and alignment onTYPE_VOIDP
Fiddle::Pointer
behave more like MRIa.
#[]
now gets the correct number of bytes, regardless of null-terminatorsb. Added
Pointer#[]=
c.
#to_s
and#to_str
should behave differently whenlen
is omitted. Notably,#to_s
takes in to account null-terminators, whileto_str
uses the Pointer sized. Throw
DLError
instead of FFI errors in some casese.
Pointer.new
accepts anything that can be converted to an Integer as an address, usingInteger()
f. Added
Pointer#free
andPointer#free=
.@free
is now stored as an integer.g.
Pointer.malloc
does not assign a defaultfree
function to the resulting pointerh. Added
Ponter#==
andPointer#<=>
Fiddle
module, notablya.
Fiddle.malloc
andFiddle.free
, which map directly to theirlibc
counterpartsb.
Fiddle::RUBY_FREE
, which is just the Integer memory address of thelibc
free
functionc.
Fiddle::BUILD_RUBY_PLATFORM
, which I've just set toRUBY_PLATFORM
, which is always"java"
d.
Fiddle::NULL
, a null pointere.
Fiddle::LibC
, an FFI wrapper tolibc
, not exactly required, but it serves to facilitate the implementation ofmalloc
andfree
(also resolves Uninitialized constant in Fiddle::Pointer.malloc #3462)fiddle/helper
in the tests, where the location oflibc
dynamic library could not be found because platform is always"java"
. Changed it so that it usesRbConfig
to detect the actual OS.There are a great deal of things I have not been able to address thus far, most notably:
Pointer.to_ptr(string)
makes a copy of the given string instead of wrapping the string itself. This is evident when you attempt to modify the data through the pointer, only to find the string was not modified. This issue affects the case of shovelling into the string, where in JRuby the Pointer data is then not reflected. I believe in order to rectify this we would have to get the address of the underlyingByteList
of the string, but i worry that this will be infeasible in Java, especially with the JVM not guaranteeing the memory address of all it's object all the time.Pointer.to_ptr(file)
does not work. Right not it will useFile#to_i
to get the address, which is obviously incorrect. MRI converts the File object to alibc
FILE, and I am unsure as to how that could be achieved in JRuby.Fiddle::Function
returns anFFI::Pointer
instead ofFiddle::Pointer
. I've made an issue here (Fiddle::Function returns FFI::Pointer instead of Fiddle::Pointer #4510)Fiddle::Function
does not accept certain values where MRI's fiddle does. For example, it does not appear to accept integers in place of pointers, or even subclasses ofFiddle::Closure
for that matter. This, and point 3, seem to be thatFiddle::Function
is just a straight-up wrapper ofFFI::Function
, so it only accepts FFI arguments and returns FFI values.Pointer.to_ptr(string)
returns a Pointer 1 byte bigger than on MRI. I think that probably has to do with null-terminators or something, although the behaviour doesn't seem to be affected if I "fix" the issue. I reverted the fix since I wanted some more input on the matter.My personal observation is that it seems JRuby's Fiddle implementation was hastily put together on top of FFI once Ruby adopted Fiddle as the defacto foreign-function interface. MRI's Fiddle is written directly on top of libffi, and in C. Perhaps it is time that JRuby's Fiddle was build directly on top of libffi/jffi, and in Java instead of Ruby.