diff options
author | Andy Wingo <wingo@pobox.com> | 2009-12-01 21:59:42 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2009-12-01 21:59:42 +0100 |
commit | 23f276dea70668b7291589de1c7d7ea7ebd9026f (patch) | |
tree | 9efe3687daed1e4d3d09d9c9b26c919dffc9890d /libguile/eval.c | |
parent | 5161a3c0d7ec59e32a637bd093644a1a5b7b8dcf (diff) | |
download | guile-23f276dea70668b7291589de1c7d7ea7ebd9026f.tar.gz |
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.
Diffstat (limited to 'libguile/eval.c')
-rw-r--r-- | libguile/eval.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/libguile/eval.c b/libguile/eval.c index 4b8cc0af3..664d66217 100644 --- a/libguile/eval.c +++ b/libguile/eval.c @@ -539,6 +539,41 @@ apply (SCM proc, SCM args) } } +SCM +scm_closure_apply (SCM proc, SCM args) +{ + unsigned int nargs; + int nreq; + SCM env; + + /* Args contains a list of all args. */ + { + int ilen = scm_ilength (args); + if (ilen < 0) + scm_wrong_num_args (proc); + nargs = ilen; + } + + nreq = SCM_CLOSURE_NUM_REQUIRED_ARGS (proc); + env = SCM_ENV (proc); + if (SCM_CLOSURE_HAS_REST_ARGS (proc)) + { + if (SCM_UNLIKELY (scm_ilength (args) < nreq)) + scm_wrong_num_args (proc); + for (; nreq; nreq--, args = CDR (args)) + env = scm_cons (CAR (args), env); + env = scm_cons (args, env); + } + else + { + for (; scm_is_pair (args); args = CDR (args), nreq--) + env = scm_cons (CAR (args), env); + if (SCM_UNLIKELY (nreq != 0)) + scm_wrong_num_args (proc); + } + return eval (SCM_CLOSURE_BODY (proc), env); +} + scm_t_option scm_eval_opts[] = { { SCM_OPTION_INTEGER, "stack", 22000, "Size of thread stacks (in machine words)." }, |