Zulip Chat Archive

Stream: lean4

Topic: Understanding Ref Counting


Marcus Rossel (Jan 09 2025 at 11:53):

This is a minimized standalone version of this question.

I'm running into error 139 (probably a segfault) when using MetaM in the FFI, which I believe is related to reference counting. Here's a minimal setup:

Lean Code

C Code

The problem I'm running into is that when check_str_impl is called more than once, then error 139 occurs. I'm guessing this is because I'm violating the following responsibility stated in the FFI section of the Lean Manual:

By default, all lean_object * parameters of an @[extern] function are considered owned, i.e. the external code is passed a "virtual RC token" and is responsible for passing this token along to another consuming function (exactly once) or freeing it via lean_dec.

What would I need to do in order to pass these "virtual RC tokens" to check_str_impl more than once? Or how can I make check_str_impl non-consuming (and what does that mean exactly)?

Rudi Schneider (Jan 09 2025 at 14:00):

I could imagine that we'd need to call lean_inc on the objects that we pass to check_str_impl?
At least I assume that check_str_impl will "drop" its inputs, and thus call lean_dec on them.

Henrik Böving (Jan 09 2025 at 18:03):

Yes if you look at the IR you can see

[result]
def checkStrImpl (x_1 : obj) (x_2 : obj) (x_3 : obj) (x_4 : obj) (x_5 : obj) (x_6 : obj) : obj :=
  dec x_5;
  dec x_4;
  dec x_3;
  let x_7 : obj := proj[2] x_2;
  inc x_7;
  dec x_2;
  let x_8 : obj := ctor_0[Lean.Name.anonymous._impl];
  let x_9 : obj := Lean.Name.str._override x_8 x_1;
  let x_10 : u8 := Lean.LocalContext.usesUserName x_7 x_9;
  dec x_9;
  dec x_7;
  let x_11 : obj := box x_10;
  let x_12 : obj := ctor_0[EStateM.Result.ok] x_11 x_6;
  ret x_12

Marcus Rossel (Jan 09 2025 at 18:23):

Oh my god, it works! Thank you :)


Last updated: May 02 2025 at 03:31 UTC