guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Passing SCM values around as void *


From: divoplade
Subject: Passing SCM values around as void *
Date: Mon, 21 Sep 2020 22:18:29 +0200
User-agent: Evolution 3.34.2

Hello guile users,

I have just found out a non-reproducible bug in my code on a (more
complex) version of this. Since it is not reproducible anyway, I will
not put a full example. This is just pseudo-code.

/* This function calls get with ctx until it is satisfied. get should
fill its third argument with as many bytes as its second argument. */
void work (void *ctx, int (*get) (void *, size_t, char *));

/* The guile callback returns a bytevector */
static void
get_as_scm (void *ctx, size_t n, char *dest)
{
  SCM *f = ctx;
  SCM ret = scm_call_1 (*f, scm_from_size_t (n));
  SCM_ASSERT (scm_c_bytevector_length (ret) == n, 
             *f, SCM_ARG1, "work");
  memcpy (dest, SCM_BYTEVECTOR_CONTENTS (ret), n);
}

static SCM
guile_work (SCM arg)
{
  void *ctx = &arg;
  work (ctx, get_as_scm);

  // This fixes the bug, it seems.
  scm_remember_upto_here_1 (arg);
}

I do not seem to have a bug if the callback does not allocate a return
value.

The underlying question is: how to pass SCM values as void *, and still
protect them from garbage collection? Do I need to call
scm_remember_upto_here_1 manually like I did, without any hint in the
manual, or is it just hiding the bug? It seems that the problem does
not happen with guile 2.2.

Best regards,

divoplade




reply via email to

[Prev in Thread] Current Thread [Next in Thread]