I use this method to interop c-code compiled logic programs o guile,

note: I saw that there have been restructuring the call logic somewhat
meaning that
the dispatching to the logic c code get's a little more expensive and a
little more different then presented below bot hey we can fix my code later
on!

Assume that we add a check for a data-structure representing a c code
closure that is located last in the chain of tests for special callable
structures just to be defensive to other
systems who want to call!

this check in call, tail-call and mv-call can then point to the different
goto labels in the supplied file (let's forget about mv-call for now) Then
the execution of the c-code will be done by starting a trampoline. This
trampoline assumes c functions that takes an argument representing the call
stack, the number of arguments, a pointer to the list of closure variables
and optionally a pointer representing the end of the stack. the function
assumes it return a integer. If it is possitive then there has been a new
function and arguments loaded into the old functions possition e.g. an
ordinary tail call from c land, the integer is the number of arguments for
this tail call. If the integer is negative then a return has been done with
the absolute value of the return representing the number of returned values
- useful information for mv-call logic.

Currently the c closure is represented as a cons of a tag with a vector
consisting of an integerization of the function pointer and closure data.
This should be changed later on but for now it's the right thing because of
the transparancy. (later on a smob would be a better fit)

By the way smob checks seems to be a little expensive, I noted that my
logic code spend a lot of time in these smob tests and wonders if the tests
for smob identity can be optimized?

So the basic code for handling this logic is attached to this document.

Coding c code using this method is error prone and perhaps not that useful
as an official interface to C-land. On the other hand I have a macro system
in scheme that transform a mix of scheme and C inspired language out to C
and using this system the interfacing is automated (I can actually write
logic programming code and it compiled it directly to C). It's just a proof
of concept right now and is a way to test the limits of the logic framework
(guile-log) I've coded on for some time.

So Comments lpease there might be some details I'm missing and also iI
wouldlike to have comments if it would be possible to include such a system
and maybe put it in relation to how we intend to use naitive code in the
future! On the other hand, apart from the bloat, the wished for changes to
the code base is not that intrusive so we could as well implement this
so that people can play with the logic system even on the c-level without
needing to recompile a patched guile!

/Stefan






On Tue, May 15, 2012 at 10:38 PM, Andy Wingo <[email protected]> wrote:

> On Wed 09 May 2012 18:07, Stefan Israelsson Tampe <[email protected]>
> writes:
>
> > I post here a directory of patches and code that can be used to enhance
> guile to interact nicely
> > with logic programming code written in C. I can reach very good
> performance using this tool
> > please have a look and comment on it.
>
> Would you mind attaching them to the message directly?  It's easier to
> read and comment that way.
>
> If you want, you can do the linux kernel thing of one patch per
> message.  But as you like.
>
> Cheers,
>
> Andy
> --
> http://wingolog.org/
>
#define NUM2PTR(x) ((SCM *) (SCM_UNPACK(x) & ~2))
{
  //C trampolines
  int ret; SCM *spp;
  const SCM *vec;
  int (*subr)(SCM **spp, int nargs, const SCM *closure, const SCM *end);


  
 vm_c_call:

  //printf("c call!\n");

  vec  = SCM_I_VECTOR_ELTS(SCM_CDR(program));

  
  //VM_HANDLE_INTERRUPTS;
  //SYNC_REGISTER ();
  
  spp  =  sp;
  SCM *sp_old = sp;
  //printf("dp %p\n",sp);
  subr = (subr_type) NUM2PTR(vec[0]);
  ret  = subr(&spp,nargs,vec + 1,stack_limit);

  //CACHE_REGISTER ();  

  sp   = spp;
  if(ret<0) 
    {
      //printf("return call\n");
      sp = sp + ret - 2;
      sp[0] = sp[-ret + 2];      
      //printf("dp %p, n = %d\n",(void *)(sp_old-sp), nargs);
      program = SCM_FRAME_PROGRAM (fp);
      NEXT;
    }

  nargs   = ret;
  program = sp[-nargs];
  
  if(SCM_CONSP(program) && scm_is_eq(SCM_CAR(program),c_closure_tag))
    goto vm_c_call;
  
  goto vm_call;

 vm_c_tail_call:
  vec = SCM_I_VECTOR_ELTS(SCM_CDR(program));
  subr    = (subr_type) NUM2PTR(vec[0]);

  //printf("c tail call!\n");
  
  //VM_HANDLE_INTERRUPTS;
  //SYNC_REGISTER ();
  

  spp = sp;
  ret = subr(&spp, nargs, vec + 1, stack_limit);

  //CACHE_REGISTER ();

  sp = spp;

  if(ret<0) 
    {
      sp = sp + ret + 1;
      goto vm_return;
    }

  nargs = ret;

  program = sp[-nargs];
  
  if(SCM_CONSP(program) && scm_is_eq(SCM_CAR(program),c_closure_tag))
    goto vm_c_tail_call;

  goto vm_tail_call;
}

Reply via email to