1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-14 15:40:19 +02:00

first step to make the vm stop calling the interpreter

* libguile/eval.h:
* libguile/eval.c (scm_closure_apply): New function, applies a closure.
  Won't be necessary in the future, but for now here it is, with
  internal linkage.

* libguile/gsubr.h:
* libguile/gsubr.c (scm_i_gsubr_apply_array): New function, applies a
  gsubr to an array of values, potentially extending that array for
  optional arguments and rest arguments and such.

* libguile/vm.c (apply_foreign): New function, applies a foreign
  function to arguments on the stack, in place.

* libguile/vm-i-system.c (call): Add a case for procedures-with-setters
  (will go away when they are applicable structs). Instead of calling
  the evaluator for foreign functions, call apply_foreign.
This commit is contained in:
Andy Wingo 2009-12-01 21:59:42 +01:00
parent 5161a3c0d7
commit 23f276dea7
6 changed files with 224 additions and 13 deletions

View file

@ -766,32 +766,38 @@ VM_DEFINE_INSTRUCTION (53, call, "call", 1, -1, 1)
sp[-nargs] = SCM_STRUCT_PROCEDURE (x);
goto vm_call;
}
else if (SCM_PROCEDURE_WITH_SETTER_P (x))
{
sp[-nargs] = SCM_PROCEDURE (x);
goto vm_call;
}
/*
* Other interpreted or compiled call
*/
if (!scm_is_false (scm_procedure_p (x)))
{
SCM args;
SCM ret;
/* At this point, the stack contains the frame, the procedure and each one
of its arguments. */
POP_LIST (nargs);
POP (args);
DROP (); /* drop the procedure */
SYNC_REGISTER ();
ret = apply_foreign (sp[-nargs],
sp - nargs + 1,
nargs,
vp->stack_limit - sp + 1);
NULLSTACK_FOR_NONLOCAL_EXIT ();
DROPN (nargs + 1); /* drop args and procedure */
DROP_FRAME ();
SYNC_REGISTER ();
PUSH (scm_apply (x, args, SCM_EOL));
NULLSTACK_FOR_NONLOCAL_EXIT ();
if (SCM_UNLIKELY (SCM_VALUESP (*sp)))
if (SCM_UNLIKELY (SCM_VALUESP (ret)))
{
/* truncate values */
SCM values;
POP (values);
values = scm_struct_ref (values, SCM_INUM0);
if (scm_is_null (values))
ret = scm_struct_ref (ret, SCM_INUM0);
if (scm_is_null (ret))
goto vm_error_not_enough_values;
PUSH (SCM_CAR (values));
PUSH (SCM_CAR (ret));
}
else
PUSH (ret);
NEXT;
}