<discocaml>
<leostera> // save `ocaml_value` for later
<discocaml>
<leostera> ```
<discocaml>
<leostera>
<discocaml>
<leostera> and then eventually I get that `ocaml_value` and i use `Store_field` to reconstruct a record that will be a response.
<discocaml>
<leostera> i'm reading through the C FFI docs, and i've been searching github for calls to `caml_register_generational_global_root` , but I'm not sure that what I have is working 🤔
<discocaml>
<leostera> what's the right way of safely storing an OCaml value pointer into a C struct?
czy has joined #ocaml
alexherbo2 has quit [Ping timeout: 250 seconds]
Tuplanolla has quit [Quit: Leaving.]
average has quit [Quit: Connection closed for inactivity]
pi3ce has joined #ocaml
rgrinberg has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
meritamen has joined #ocaml
meritamen has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
jmcantrell has joined #ocaml
rgrinberg has joined #ocaml
rgrinberg has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
omegatron has quit [Quit: Power is a curious thing. It can be contained, hidden, locked away, and yet it always breaks free.]
justache- is now known as justache
meritamen has joined #ocaml
jmcantrell has quit [Quit: WeeChat 4.1.2]
rgrinberg has joined #ocaml
jmcantrell has joined #ocaml
rgrinberg has quit [Ping timeout: 256 seconds]
trev has joined #ocaml
azimut has quit [Remote host closed the connection]
azimut has joined #ocaml
azimut has quit [Remote host closed the connection]
azimut has joined #ocaml
rgrinberg has joined #ocaml
rgrinberg has quit [Ping timeout: 256 seconds]
average has joined #ocaml
azimut has quit [Ping timeout: 240 seconds]
Serpent7776 has joined #ocaml
wingsorc has quit [Quit: Leaving]
bartholin has joined #ocaml
average has quit [Quit: Connection closed for inactivity]
neiluj has joined #ocaml
waleee has quit [Ping timeout: 252 seconds]
alexherbo2 has joined #ocaml
<discocaml>
<octachron> You should not register a value allocated with malloc.
<discocaml>
<octachron> Registering a root informs the GC that there is an owner for a part of memory managed by the GC.
bartholin has quit [Quit: Leaving]
romildo has joined #ocaml
<discocaml>
<leostera> gotcha
<discocaml>
<leostera> i'm literally mimicking code i'm seeing in hhvm, flow, clangml, and other github projects
meritamen has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
neiluj has quit [Quit: neiluj]
neiluj has joined #ocaml
<neiluj>
Hi! with Qcheck, how do I make sure that the assume(...) that fail are not counted as passing tests?
<neiluj>
or that it retries and the number of tests specified should correspond to the number of failing+passing tests
<neiluj>
not counting skipped tests
meritamen has joined #ocaml
<discocaml>
<leostera> i'm confused, this is how i saw a lot of folks doing it on github projects, can you show me what the right way of doing this is?
romildo has quit [Quit: Leaving]
<discocaml>
<leostera> should I be registering a global root for the address of the field itself?
<Armael>
what you register as a root should be the address of a C location in memory, that stores an ocaml value
<Armael>
eg if myglob is a C global variable: value myglob = Val_unit; caml_register_generational_global_root(&myglob);
<discocaml>
<leostera> so i should be able to do: `caml_register_generational_global_root(&Field(input, 0));` ?
<Armael>
or, instead of a C global, with a malloc'd location: value* foo = malloc(sizeof(value)); *foo = Val_unit; caml_register_etc(foo);
<Armael>
no that'd register a location in ocaml memory
<Armael>
what you register as a root needs to be a C-managed bit of memory that you provide
<Armael>
&Field(...) is an address somewhere in ocaml-managed memory, you can't use that
<Armael>
(sorry, I agree it's confusing, it would be clearer with a drawing maybe…)
<discocaml>
<leostera> i'm not using a c global btw
<discocaml>
<leostera> this is what i'm doing 🤔
<discocaml>
<leostera> ok so to summarize `caml_register_generational_global_root` should receive a pointer to C-managed memory?
<discocaml>
<leostera> how do i tell the GC not to gc the ocaml value tho? 🤔
romildo has joined #ocaml
romildo has quit [Quit: Leaving]
<discocaml>
<0aty> Isn't the point simply that C-managed memory that can hold pointers to OCaml-managed memory needs to count as a GC root? I might just be stating the obvious here but I don't see how it matters if its /technically/ a C global
meritamen has quit [Remote host closed the connection]
olle has joined #ocaml
fweht has joined #ocaml
<Armael>
the C global was just an example, it works with malloc'd memory as well
<Armael>
caml_register_generational_global_root should receive a pointer to C-managed memory that stores an ocaml value
<Armael>
then the GC will not collect the value contained there
<Armael>
(the GC will also *update* the contents of the rooted C-managed memory whenever the ocaml block stored there moves around in memory...)
<discocaml>
<0aty> Even if it isnt malloced, if you have an ocaml-managed piece of memory, and you want to reference it from C, even if the reference is on the stack, you should still register it as a gc root though, right? because otherwise the Gc will clean it up under your feet
<discocaml>
<0aty> and if its on the stack, obviously deregister before the end of the stack frame so the Gc doesnt do something with a random reference into the stack
<Armael>
yes, whenever you want to reference an ocaml value from C you need to root it
<Armael>
(except in specific cases where you know you are not calling the GC (not allocating etc))
a51 has quit [Quit: WeeChat 4.1.2]
azimut has joined #ocaml
azimut has quit [Remote host closed the connection]
azimut has joined #ocaml
rgrinberg has joined #ocaml
a51 has joined #ocaml
rgrinberg has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
rgrinberg has joined #ocaml
Inline has joined #ocaml
alexherbo2 has quit [Remote host closed the connection]
alexherbo2 has joined #ocaml
rgrinberg has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
rgrinberg has joined #ocaml
average has joined #ocaml
oriba has joined #ocaml
Serpent7776 has quit [Ping timeout: 276 seconds]
rgrinberg has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
olle has quit [Ping timeout: 260 seconds]
rgrinberg has joined #ocaml
alexherbo2 has quit [Remote host closed the connection]
a51 has quit [Quit: WeeChat 4.1.2]
rgrinberg has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
neiluj has quit [Quit: neiluj]
bartholin has joined #ocaml
a51 has joined #ocaml
omegatron has joined #ocaml
waleee has joined #ocaml
fweht has quit [Quit: Connection closed for inactivity]
dylanj has joined #ocaml
<discocaml>
<octachron> @leostera , sorry for my erroneous answer (it is far better to trust Armael than me on those matters).
<discocaml>
<.armael.> At some point it’d be nice to extend/revamp the FFI page of the ocaml manual, perhaps with more drawings…
jmcantrell has quit [Quit: WeeChat 4.1.2]
trev has quit [Quit: trev]
jmcantrell has joined #ocaml
<discocaml>
<leostera> no worries 🙏🏼
jmcantrell has quit [Quit: WeeChat 4.1.2]
neiluj has joined #ocaml
jmcantrell has joined #ocaml
jmcantrell has quit [Quit: WeeChat 4.1.2]
Tuplanolla has joined #ocaml
jmcantrell has joined #ocaml
neiluj has quit [Ping timeout: 256 seconds]
bartholin has quit [Quit: Leaving]
<discocaml>
<Ada> speaking of ffi, `CArray.from_ptr pointer len |> CArray.to_list |> List.to_seq |> String.of_seq`
<discocaml>
<Ada> is there a better way to do this
<discocaml>
<._null._> Probably better not to go through a list at first
<companion_cube>
:/
<discocaml>
<Ada> yeah, thats what is really annoying me
<companion_cube>
A function with a loop, if there's a way to get individual CArray items
<discocaml>
<Kali> could you not write your own conversion function?
<discocaml>
<Kali> i know it's a little annoying but it shouldn't be more than a few lines
<discocaml>
<Ada> yeah, i was just checking before i wrote a manual loop that i'm not missing something super simple
<discocaml>
<Ada> ctypes has a built in string conversion system, but it only works on null terminated strings and this is binary data
<discocaml>
<._null._> `CArray.from_ptr pointer len |> fun a -> String.init len (CArray.get a)` ?
<Armael>
(personally now that I learned to use the "standard" C FFI I can't be bothered to use ctypes anymore...)
<discocaml>
<Ada> oh cool, somehow i didnt know about String.init
<discocaml>
<Ada> Armael: i don't know C very well and the dune ctypes generation is really appealing
<discocaml>
<Ada> the actual ctypes api is quite eh
<Armael>
ye to be fair when I was using ctypes there was no dune support and the build story was very annoying
<Armael>
tho with the normal FFI building is also fairly easy
<Armael>
I guess there's a steeper learning curve with the normal FFI, but I feel that I understand better what I'm doing
<Armael>
with ctypes I always fear that I'll get stuck in some cases where I don't know how to express what I need using the ctypes DSL
<discocaml>
<Ada> if i was gonna port something big i would definitely learn the normal ffi
<Armael>
makes sense, for smaller bindings ctypes is very convenient
<discocaml>
<Ada> thank u sm
rgrinberg has joined #ocaml
rgrinberg has quit [Client Quit]
<companion_cube>
Armael: agreed, especially given it has lower overhead afaik