1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-18 01:30:27 +02:00

Merge commit 'e20d7001c3' into vm-check

Conflicts:

	libguile/stacks.c
This commit is contained in:
Andy Wingo 2009-03-17 16:40:52 +01:00
commit 3b91e017e3
23 changed files with 281 additions and 245 deletions

5
NEWS
View file

@ -1,5 +1,5 @@
Guile NEWS --- history of user-visible changes. Guile NEWS --- history of user-visible changes.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
See the end for copying conditions. See the end for copying conditions.
Please send Guile bug reports to bug-guile@gnu.org. Please send Guile bug reports to bug-guile@gnu.org.
@ -40,6 +40,9 @@ application code.
** Functions for handling `scm_option' now no longer require an argument ** Functions for handling `scm_option' now no longer require an argument
indicating length of the `scm_t_option' array. indicating length of the `scm_t_option' array.
** Primitive procedures (aka. "subrs") are now stored in double cells
This removes the subr table and simplifies the code.
Changes in 1.8.7 (since 1.8.6) Changes in 1.8.7 (since 1.8.6)

View file

@ -3,6 +3,7 @@ SCM_BENCHMARKS = benchmarks/0-reference.bm \
benchmarks/if.bm \ benchmarks/if.bm \
benchmarks/logand.bm \ benchmarks/logand.bm \
benchmarks/read.bm \ benchmarks/read.bm \
benchmarks/subr.bm \
benchmarks/uniform-vector-read.bm benchmarks/uniform-vector-read.bm
EXTRA_DIST = guile-benchmark lib.scm $(SCM_BENCHMARKS) \ EXTRA_DIST = guile-benchmark lib.scm $(SCM_BENCHMARKS) \

View file

@ -0,0 +1,46 @@
;;; subr.bm --- Measure the subr invocation cost. -*- Scheme -*-
;;;
;;; Copyright (C) 2009 Free Software Foundation, Inc.
;;;
;;; This program is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 2, or (at your option)
;;; any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this software; see the file COPYING. If not, write to
;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;;; Boston, MA 02110-1301 USA
(define-module (benchmarks subrs)
:use-module (benchmark-suite lib))
(with-benchmark-prefix "subr invocation"
(benchmark "simple subr" 700000
;; 1 required argument, 0 optional arguments, no rest.
(1+ 0))
(benchmark "generic subr" 700000
;; 2 required arguments, 4 optional arguments, no rest.
;; In Guile 1.8 and earlier, such subrs are implemented as "compiled
;; closures" (cclos). There, when a cclo/gsubr is called, the evaluator
;; goes through `SCM_APPLY ()' and conses the arguments, which is more
;; costly than the invocation of a "simple subr".
(string= "foo" "bar")))
(with-benchmark-prefix "subr application"
(benchmark "simple subr" 700000
(apply 1+ '(0)))
(benchmark "generic subr" 700000
(apply string= "foo" '("bar"))))

View file

@ -3,7 +3,7 @@
#ifndef SCM___SCM_H #ifndef SCM___SCM_H
#define SCM___SCM_H #define SCM___SCM_H
/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002,2003, 2006, 2007, 2008 Free Software Foundation, Inc. /* Copyright (C) 1995,1996,1998,1999,2000,2001,2002,2003, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -140,8 +140,6 @@
*/ */
#define CCLO
/* Guile Scheme supports the #f/() distinction; Guile Lisp won't. We /* Guile Scheme supports the #f/() distinction; Guile Lisp won't. We
have horrible plans for their unification. */ have horrible plans for their unification. */
#undef SICP #undef SICP

View file

@ -1,5 +1,5 @@
/* Debugging extensions for Guile /* Debugging extensions for Guile
* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2006, 2008 Free Software Foundation * Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2006, 2008, 2009 Free Software Foundation
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -357,9 +357,6 @@ SCM_DEFINE (scm_procedure_source, "procedure-source", 1, 0, 0,
if (!SCM_SMOB_DESCRIPTOR (proc).apply) if (!SCM_SMOB_DESCRIPTOR (proc).apply)
break; break;
case scm_tcs_subrs: case scm_tcs_subrs:
#ifdef CCLO
case scm_tc7_cclo:
#endif
procprop: procprop:
/* It would indeed be a nice thing if we supplied source even for /* It would indeed be a nice thing if we supplied source even for
built in procedures! */ built in procedures! */
@ -390,9 +387,6 @@ SCM_DEFINE (scm_procedure_environment, "procedure-environment", 1, 0, 0,
case scm_tcs_closures: case scm_tcs_closures:
return SCM_ENV (proc); return SCM_ENV (proc);
case scm_tcs_subrs: case scm_tcs_subrs:
#ifdef CCLO
case scm_tc7_cclo:
#endif
return SCM_EOL; return SCM_EOL;
default: default:
SCM_WRONG_TYPE_ARG (1, proc); SCM_WRONG_TYPE_ARG (1, proc);

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009
* Free Software Foundation, Inc. * Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -3269,7 +3269,7 @@ scm_trampoline_0 (SCM proc)
break; break;
case scm_tc7_asubr: case scm_tc7_asubr:
case scm_tc7_rpsubr: case scm_tc7_rpsubr:
case scm_tc7_cclo: case scm_tc7_gsubr:
case scm_tc7_pws: case scm_tc7_pws:
trampoline = scm_call_0; trampoline = scm_call_0;
break; break;
@ -3395,7 +3395,7 @@ scm_trampoline_1 (SCM proc)
break; break;
case scm_tc7_asubr: case scm_tc7_asubr:
case scm_tc7_rpsubr: case scm_tc7_rpsubr:
case scm_tc7_cclo: case scm_tc7_gsubr:
case scm_tc7_pws: case scm_tc7_pws:
trampoline = scm_call_1; trampoline = scm_call_1;
break; break;
@ -3489,7 +3489,7 @@ scm_trampoline_2 (SCM proc)
else else
return NULL; return NULL;
break; break;
case scm_tc7_cclo: case scm_tc7_gsubr:
case scm_tc7_pws: case scm_tc7_pws:
trampoline = scm_call_2; trampoline = scm_call_2;
break; break;

View file

@ -1,7 +1,7 @@
/* /*
* eval.i.c - actual evaluator code for GUILE * eval.i.c - actual evaluator code for GUILE
* *
* Copyright (C) 2002, 03, 04, 05, 06, 07 Free Software Foundation, Inc. * Copyright (C) 2002, 03, 04, 05, 06, 07, 09 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -1135,14 +1135,12 @@ dispatch:
if (!SCM_SMOB_APPLICABLE_P (proc)) if (!SCM_SMOB_APPLICABLE_P (proc))
goto badfun; goto badfun;
RETURN (SCM_SMOB_APPLY_0 (proc)); RETURN (SCM_SMOB_APPLY_0 (proc));
case scm_tc7_cclo: case scm_tc7_gsubr:
arg1 = proc;
proc = SCM_CCLO_SUBR (proc);
#ifdef DEVAL #ifdef DEVAL
debug.info->a.proc = proc; debug.info->a.proc = proc;
debug.info->a.args = scm_list_1 (arg1); debug.info->a.args = SCM_EOL;
#endif #endif
goto evap1; RETURN (scm_gsubr_apply (scm_list_1 (proc)));
case scm_tc7_pws: case scm_tc7_pws:
proc = SCM_PROCEDURE (proc); proc = SCM_PROCEDURE (proc);
#ifdef DEVAL #ifdef DEVAL
@ -1256,15 +1254,12 @@ dispatch:
if (!SCM_SMOB_APPLICABLE_P (proc)) if (!SCM_SMOB_APPLICABLE_P (proc))
goto badfun; goto badfun;
RETURN (SCM_SMOB_APPLY_1 (proc, arg1)); RETURN (SCM_SMOB_APPLY_1 (proc, arg1));
case scm_tc7_cclo: case scm_tc7_gsubr:
arg2 = arg1;
arg1 = proc;
proc = SCM_CCLO_SUBR (proc);
#ifdef DEVAL #ifdef DEVAL
debug.info->a.args = scm_cons (arg1, debug.info->a.args); debug.info->a.args = scm_cons (arg1, debug.info->a.args);
debug.info->a.proc = proc; debug.info->a.proc = proc;
#endif #endif
goto evap2; RETURN (scm_gsubr_apply (scm_list_2 (proc, arg1)));
case scm_tc7_pws: case scm_tc7_pws:
proc = SCM_PROCEDURE (proc); proc = SCM_PROCEDURE (proc);
#ifdef DEVAL #ifdef DEVAL
@ -1362,19 +1357,14 @@ dispatch:
goto badfun; goto badfun;
RETURN (SCM_SMOB_APPLY_2 (proc, arg1, arg2)); RETURN (SCM_SMOB_APPLY_2 (proc, arg1, arg2));
cclon: cclon:
case scm_tc7_cclo: case scm_tc7_gsubr:
#ifdef DEVAL #ifdef DEVAL
RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc), RETURN (scm_gsubr_apply (scm_cons (proc, debug.info->a.args)));
scm_cons (proc, debug.info->a.args),
SCM_EOL));
#else #else
RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc), RETURN (scm_gsubr_apply
scm_cons2 (proc, arg1, (scm_cons (proc,
scm_cons (arg2, scm_cons2 (arg1, arg2,
scm_ceval_args (x, scm_ceval_args (x, env, proc)))));
env,
proc))),
SCM_EOL));
#endif #endif
case scm_tcs_struct: case scm_tcs_struct:
if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC) if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
@ -1503,7 +1493,7 @@ dispatch:
goto badfun; goto badfun;
RETURN (SCM_SMOB_APPLY_3 (proc, arg1, arg2, RETURN (SCM_SMOB_APPLY_3 (proc, arg1, arg2,
SCM_CDDR (debug.info->a.args))); SCM_CDDR (debug.info->a.args)));
case scm_tc7_cclo: case scm_tc7_gsubr:
goto cclon; goto cclon;
case scm_tc7_pws: case scm_tc7_pws:
proc = SCM_PROCEDURE (proc); proc = SCM_PROCEDURE (proc);
@ -1566,7 +1556,7 @@ dispatch:
goto badfun; goto badfun;
RETURN (SCM_SMOB_APPLY_3 (proc, arg1, arg2, RETURN (SCM_SMOB_APPLY_3 (proc, arg1, arg2,
scm_ceval_args (x, env, proc))); scm_ceval_args (x, env, proc)));
case scm_tc7_cclo: case scm_tc7_gsubr:
goto cclon; goto cclon;
case scm_tc7_pws: case scm_tc7_pws:
proc = SCM_PROCEDURE (proc); proc = SCM_PROCEDURE (proc);
@ -1878,19 +1868,15 @@ tail:
RETURN (SCM_SMOB_APPLY_2 (proc, arg1, SCM_CAR (args))); RETURN (SCM_SMOB_APPLY_2 (proc, arg1, SCM_CAR (args)));
else else
RETURN (SCM_SMOB_APPLY_3 (proc, arg1, SCM_CAR (args), SCM_CDR (args))); RETURN (SCM_SMOB_APPLY_3 (proc, arg1, SCM_CAR (args), SCM_CDR (args)));
case scm_tc7_cclo: case scm_tc7_gsubr:
#ifdef DEVAL #ifdef DEVAL
args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args); args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
arg1 = proc;
proc = SCM_CCLO_SUBR (proc);
debug.vect[0].a.proc = proc; debug.vect[0].a.proc = proc;
debug.vect[0].a.args = scm_cons (arg1, args); debug.vect[0].a.args = scm_cons (arg1, args);
#else #else
args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args)); args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
arg1 = proc;
proc = SCM_CCLO_SUBR (proc);
#endif #endif
goto tail; RETURN (scm_gsubr_apply (scm_cons (proc, args)));
case scm_tc7_pws: case scm_tc7_pws:
proc = SCM_PROCEDURE (proc); proc = SCM_PROCEDURE (proc);
#ifdef DEVAL #ifdef DEVAL

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1998,1999,2000,2001,2002,2003, 2006, 2008 Free Software Foundation, Inc. /* Copyright (C) 1998,1999,2000,2001,2002,2003, 2006, 2008, 2009 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -106,7 +106,6 @@ SCM_DEFINE (scm_self_evaluating_p, "self-evaluating?", 1, 0, 0,
case scm_tc7_number: case scm_tc7_number:
case scm_tc7_string: case scm_tc7_string:
case scm_tc7_smob: case scm_tc7_smob:
case scm_tc7_cclo:
case scm_tc7_pws: case scm_tc7_pws:
case scm_tcs_subrs: case scm_tcs_subrs:
case scm_tcs_struct: case scm_tcs_struct:

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -131,14 +131,6 @@ scm_i_sweep_card (scm_t_cell *card, SCM *free_list, scm_t_heap_segment *seg)
scm_i_vector_free (scmptr); scm_i_vector_free (scmptr);
break; break;
#ifdef CCLO
case scm_tc7_cclo:
scm_gc_free (SCM_CCLO_BASE (scmptr),
SCM_CCLO_LENGTH (scmptr) * sizeof (SCM),
"compiled closure");
break;
#endif
case scm_tc7_number: case scm_tc7_number:
switch SCM_TYP16 (scmptr) switch SCM_TYP16 (scmptr)
{ {
@ -397,10 +389,6 @@ scm_i_tag_name (scm_t_bits tag)
return "weak vector"; return "weak vector";
case scm_tc7_vector: case scm_tc7_vector:
return "vector"; return "vector";
#ifdef CCLO
case scm_tc7_cclo:
return "compiled closure";
#endif
case scm_tc7_number: case scm_tc7_number:
switch (tag) switch (tag)
{ {

View file

@ -294,21 +294,6 @@ scm_gc_mark_dependencies (SCM p)
} }
ptr = SCM_SIMPLE_VECTOR_REF (ptr, 0); ptr = SCM_SIMPLE_VECTOR_REF (ptr, 0);
goto gc_mark_loop; goto gc_mark_loop;
#ifdef CCLO
case scm_tc7_cclo:
{
size_t i = SCM_CCLO_LENGTH (ptr);
size_t j;
for (j = 1; j != i; ++j)
{
SCM obj = SCM_CCLO_REF (ptr, j);
if (!SCM_IMP (obj))
scm_gc_mark (obj);
}
ptr = SCM_CCLO_REF (ptr, 0);
goto gc_mark_loop;
}
#endif
case scm_tc7_string: case scm_tc7_string:
ptr = scm_i_string_mark (ptr); ptr = scm_i_string_mark (ptr);

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004,2008 /* Copyright (C) 1998,1999,2000,2001,2002,2003,2004,2008,2009
* Free Software Foundation, Inc. * Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -239,7 +239,7 @@ SCM_DEFINE (scm_class_of, "class-of", 1, 0, 0,
return scm_class_primitive_generic; return scm_class_primitive_generic;
else else
return scm_class_procedure; return scm_class_procedure;
case scm_tc7_cclo: case scm_tc7_gsubr:
return scm_class_procedure; return scm_class_procedure;
case scm_tc7_pws: case scm_tc7_pws:
return scm_class_procedure_with_setter; return scm_class_procedure_with_setter;

View file

@ -40,11 +40,10 @@
SCM_GLOBAL_SYMBOL (scm_sym_name, "name"); SCM_GLOBAL_SYMBOL (scm_sym_name, "name");
SCM scm_f_gsubr_apply;
static SCM static SCM
create_gsubr (int define, const char *name, create_gsubr (int define, const char *name,
int req, int opt, int rst, SCM (*fcn)()) unsigned int req, unsigned int opt, unsigned int rst,
SCM (*fcn) ())
{ {
SCM subr; SCM subr;
@ -52,53 +51,47 @@ create_gsubr (int define, const char *name,
{ {
case SCM_GSUBR_MAKTYPE(0, 0, 0): case SCM_GSUBR_MAKTYPE(0, 0, 0):
subr = scm_c_make_subr (name, scm_tc7_subr_0, fcn); subr = scm_c_make_subr (name, scm_tc7_subr_0, fcn);
goto create_subr; break;
case SCM_GSUBR_MAKTYPE(1, 0, 0): case SCM_GSUBR_MAKTYPE(1, 0, 0):
subr = scm_c_make_subr (name, scm_tc7_subr_1, fcn); subr = scm_c_make_subr (name, scm_tc7_subr_1, fcn);
goto create_subr; break;
case SCM_GSUBR_MAKTYPE(0, 1, 0): case SCM_GSUBR_MAKTYPE(0, 1, 0):
subr = scm_c_make_subr (name, scm_tc7_subr_1o, fcn); subr = scm_c_make_subr (name, scm_tc7_subr_1o, fcn);
goto create_subr; break;
case SCM_GSUBR_MAKTYPE(1, 1, 0): case SCM_GSUBR_MAKTYPE(1, 1, 0):
subr = scm_c_make_subr (name, scm_tc7_subr_2o, fcn); subr = scm_c_make_subr (name, scm_tc7_subr_2o, fcn);
goto create_subr; break;
case SCM_GSUBR_MAKTYPE(2, 0, 0): case SCM_GSUBR_MAKTYPE(2, 0, 0):
subr = scm_c_make_subr (name, scm_tc7_subr_2, fcn); subr = scm_c_make_subr (name, scm_tc7_subr_2, fcn);
goto create_subr; break;
case SCM_GSUBR_MAKTYPE(3, 0, 0): case SCM_GSUBR_MAKTYPE(3, 0, 0):
subr = scm_c_make_subr (name, scm_tc7_subr_3, fcn); subr = scm_c_make_subr (name, scm_tc7_subr_3, fcn);
goto create_subr; break;
case SCM_GSUBR_MAKTYPE(0, 0, 1): case SCM_GSUBR_MAKTYPE(0, 0, 1):
subr = scm_c_make_subr (name, scm_tc7_lsubr, fcn); subr = scm_c_make_subr (name, scm_tc7_lsubr, fcn);
goto create_subr; break;
case SCM_GSUBR_MAKTYPE(2, 0, 1): case SCM_GSUBR_MAKTYPE(2, 0, 1):
subr = scm_c_make_subr (name, scm_tc7_lsubr_2, fcn); subr = scm_c_make_subr (name, scm_tc7_lsubr_2, fcn);
create_subr: break;
if (define)
scm_define (SCM_SNAME (subr), subr);
return subr;
default: default:
{ {
SCM cclo = scm_makcclo (scm_f_gsubr_apply, 3L); unsigned type;
SCM subr = scm_c_make_subr (name, scm_tc7_subr_0, fcn);
SCM sym = SCM_SNAME (subr); type = SCM_GSUBR_MAKTYPE (req, opt, rst);
if (SCM_GSUBR_MAX < req + opt + rst) if (SCM_GSUBR_REQ (type) != req
{ || SCM_GSUBR_OPT (type) != opt
fprintf (stderr, || SCM_GSUBR_REST (type) != rst)
"ERROR in scm_c_make_gsubr: too many args (%d) to %s\n", scm_out_of_range ("create_gsubr", scm_from_uint (req + opt + rst));
req + opt + rst, name);
exit (1); subr = scm_c_make_subr (name, scm_tc7_gsubr | (type << 8U),
} fcn);
SCM_SET_GSUBR_PROC (cclo, subr);
SCM_SET_GSUBR_TYPE (cclo,
scm_from_int (SCM_GSUBR_MAKTYPE (req, opt, rst)));
if (SCM_REC_PROCNAMES_P)
scm_set_procedure_property_x (cclo, scm_sym_name, sym);
if (define)
scm_define (sym, cclo);
return cclo;
} }
} }
if (define)
scm_define (SCM_SNAME (subr), subr);
return subr;
} }
SCM SCM
@ -190,20 +183,15 @@ scm_gsubr_apply (SCM args)
#define FUNC_NAME "scm_gsubr_apply" #define FUNC_NAME "scm_gsubr_apply"
{ {
SCM self = SCM_CAR (args); SCM self = SCM_CAR (args);
SCM (*fcn)() = SCM_SUBRF (SCM_GSUBR_PROC (self)); SCM (*fcn)() = SCM_SUBRF (self);
SCM v[SCM_GSUBR_MAX]; SCM v[SCM_GSUBR_MAX];
int typ = scm_to_int (SCM_GSUBR_TYPE (self)); unsigned int typ = SCM_GSUBR_TYPE (self);
long i, n = SCM_GSUBR_REQ (typ) + SCM_GSUBR_OPT (typ) + SCM_GSUBR_REST (typ); long i, n = SCM_GSUBR_REQ (typ) + SCM_GSUBR_OPT (typ) + SCM_GSUBR_REST (typ);
#if 0
if (n > SCM_GSUBR_MAX)
scm_misc_error (FUNC_NAME,
"Function ~S has illegal arity ~S.",
scm_list_2 (self, scm_from_int (n)));
#endif
args = SCM_CDR (args); args = SCM_CDR (args);
for (i = 0; i < SCM_GSUBR_REQ (typ); i++) { for (i = 0; i < SCM_GSUBR_REQ (typ); i++) {
if (scm_is_null (args)) if (scm_is_null (args))
scm_wrong_num_args (SCM_SNAME (SCM_GSUBR_PROC (self))); scm_wrong_num_args (SCM_SNAME (self));
v[i] = SCM_CAR(args); v[i] = SCM_CAR(args);
args = SCM_CDR(args); args = SCM_CDR(args);
} }
@ -218,7 +206,7 @@ scm_gsubr_apply (SCM args)
if (SCM_GSUBR_REST(typ)) if (SCM_GSUBR_REST(typ))
v[i] = args; v[i] = args;
else if (!scm_is_null (args)) else if (!scm_is_null (args))
scm_wrong_num_args (SCM_SNAME (SCM_GSUBR_PROC (self))); scm_wrong_num_args (SCM_SNAME (self));
switch (n) { switch (n) {
case 2: return (*fcn)(v[0], v[1]); case 2: return (*fcn)(v[0], v[1]);
case 3: return (*fcn)(v[0], v[1], v[2]); case 3: return (*fcn)(v[0], v[1], v[2]);
@ -229,6 +217,10 @@ scm_gsubr_apply (SCM args)
case 8: return (*fcn)(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); case 8: return (*fcn)(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
case 9: return (*fcn)(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8]); case 9: return (*fcn)(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8]);
case 10: return (*fcn)(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9]); case 10: return (*fcn)(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9]);
default:
scm_misc_error ((char *) SCM_SNAME (self),
"gsubr invocation with more than 10 arguments not implemented",
SCM_EOL);
} }
return SCM_BOOL_F; /* Never reached. */ return SCM_BOOL_F; /* Never reached. */
} }
@ -259,8 +251,6 @@ gsubr_21l(SCM req1, SCM req2, SCM opt, SCM rst)
void void
scm_init_gsubr() scm_init_gsubr()
{ {
scm_f_gsubr_apply = scm_c_make_subr ("gsubr-apply", scm_tc7_lsubr,
scm_gsubr_apply);
#ifdef GSUBR_TEST #ifdef GSUBR_TEST
scm_c_define_gsubr ("gsubr-2-1-l", 2, 1, 1, gsubr_21l); /* example */ scm_c_define_gsubr ("gsubr-2-1-l", 2, 1, 1, gsubr_21l); /* example */
#endif #endif

View file

@ -3,7 +3,7 @@
#ifndef SCM_GSUBR_H #ifndef SCM_GSUBR_H
#define SCM_GSUBR_H #define SCM_GSUBR_H
/* Copyright (C) 1995,1996,1998,2000,2001, 2006, 2008 Free Software Foundation, Inc. /* Copyright (C) 1995,1996,1998,2000,2001, 2006, 2008, 2009 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -26,19 +26,17 @@
/* Return an integer describing the arity of GSUBR, a subr of type
`scm_tc7_gsubr'. The result can be interpreted with `SCM_GSUBR_REQ ()'
and similar. */
#define SCM_GSUBR_TYPE(gsubr) (SCM_CELL_TYPE (gsubr) >> 8)
#define SCM_GSUBR_MAKTYPE(req, opt, rst) ((req)|((opt)<<4)|((rst)<<8)) #define SCM_GSUBR_MAKTYPE(req, opt, rst) ((req)|((opt)<<4)|((rst)<<8))
#define SCM_GSUBR_MAX 33
#define SCM_GSUBR_REQ(x) ((long)(x)&0xf) #define SCM_GSUBR_REQ(x) ((long)(x)&0xf)
#define SCM_GSUBR_OPT(x) (((long)(x)&0xf0)>>4) #define SCM_GSUBR_OPT(x) (((long)(x)&0xf0)>>4)
#define SCM_GSUBR_REST(x) ((long)(x)>>8) #define SCM_GSUBR_REST(x) ((long)(x)>>8)
#define SCM_GSUBR_MAX 10
#define SCM_GSUBR_TYPE(cclo) (SCM_CCLO_REF ((cclo), 1))
#define SCM_SET_GSUBR_TYPE(cclo, type) (SCM_CCLO_SET ((cclo), 1, (type)))
#define SCM_GSUBR_PROC(cclo) (SCM_CCLO_REF ((cclo), 2))
#define SCM_SET_GSUBR_PROC(cclo, proc) (SCM_CCLO_SET ((cclo), 2, (proc)))
SCM_API SCM scm_f_gsubr_apply;
SCM_API SCM scm_c_make_gsubr (const char *name, SCM_API SCM scm_c_make_gsubr (const char *name,
int req, int opt, int rst, SCM (*fcn) ()); int req, int opt, int rst, SCM (*fcn) ());
SCM_API SCM scm_c_make_gsubr_with_generic (const char *name, SCM_API SCM scm_c_make_gsubr_with_generic (const char *name,

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1995-1999,2000,2001, 2002, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. /* Copyright (C) 1995-1999,2000,2001, 2002, 2003, 2004, 2006, 2008, 2009 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -657,30 +657,7 @@ iprin1 (SCM exp, SCM port, scm_print_state *pstate)
scm_puts (scm_i_symbol_chars (SCM_SNAME (exp)), port); scm_puts (scm_i_symbol_chars (SCM_SNAME (exp)), port);
scm_putc ('>', port); scm_putc ('>', port);
break; break;
#ifdef CCLO
case scm_tc7_cclo:
{
SCM proc = SCM_CCLO_SUBR (exp);
if (scm_is_eq (proc, scm_f_gsubr_apply))
{
/* Print gsubrs as primitives */
SCM name = scm_procedure_name (exp);
scm_puts ("#<primitive-procedure", port);
if (scm_is_true (name))
{
scm_putc (' ', port);
scm_puts (scm_i_symbol_chars (name), port);
}
}
else
{
scm_puts ("#<compiled-closure ", port);
scm_iprin1 (proc, port, pstate);
}
scm_putc ('>', port);
}
break;
#endif
case scm_tc7_pws: case scm_tc7_pws:
scm_puts ("#<procedure-with-setter", port); scm_puts ("#<procedure-with-setter", port);
{ {

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1995,1996,1998,2000,2001,2003,2004, 2006, 2008 Free Software Foundation, Inc. /* Copyright (C) 1995,1996,1998,2000,2001,2003,2004, 2006, 2008, 2009 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -88,21 +88,14 @@ scm_i_procedure_arity (SCM proc)
{ {
return SCM_BOOL_F; return SCM_BOOL_F;
} }
case scm_tc7_cclo: case scm_tc7_gsubr:
if (scm_is_eq (SCM_CCLO_SUBR (proc), scm_f_gsubr_apply)) {
{ unsigned int type = SCM_GSUBR_TYPE (proc);
int type = scm_to_int (SCM_GSUBR_TYPE (proc)); a = SCM_GSUBR_REQ (type);
a += SCM_GSUBR_REQ (type); o = SCM_GSUBR_OPT (type);
o = SCM_GSUBR_OPT (type); r = SCM_GSUBR_REST (type);
r = SCM_GSUBR_REST (type); break;
break; }
}
else
{
proc = SCM_CCLO_SUBR (proc);
a -= 1;
goto loop;
}
case scm_tc7_pws: case scm_tc7_pws:
proc = SCM_PROCEDURE (proc); proc = SCM_PROCEDURE (proc);
goto loop; goto loop;

View file

@ -93,39 +93,6 @@ scm_c_define_subr_with_generic (const char *name,
} }
#ifdef CCLO
SCM
scm_makcclo (SCM proc, size_t len)
{
scm_t_bits *base = scm_gc_malloc (len * sizeof (scm_t_bits),
"compiled closure");
unsigned long i;
SCM s;
for (i = 0; i < len; ++i)
base [i] = SCM_UNPACK (SCM_UNSPECIFIED);
s = scm_cell (SCM_MAKE_CCLO_TAG (len), (scm_t_bits) base);
SCM_SET_CCLO_SUBR (s, proc);
return s;
}
/* Undocumented debugging procedure */
#ifdef GUILE_DEBUG
SCM_DEFINE (scm_make_cclo, "make-cclo", 2, 0, 0,
(SCM proc, SCM len),
"Create a compiled closure for @var{proc}, which reserves\n"
"@var{len} objects for its usage.")
#define FUNC_NAME s_scm_make_cclo
{
return scm_makcclo (proc, scm_to_size_t (len));
}
#undef FUNC_NAME
#endif
#endif
SCM_DEFINE (scm_procedure_p, "procedure?", 1, 0, 0, SCM_DEFINE (scm_procedure_p, "procedure?", 1, 0, 0,
(SCM obj), (SCM obj),
"Return @code{#t} if @var{obj} is a procedure.") "Return @code{#t} if @var{obj} is a procedure.")
@ -139,9 +106,6 @@ SCM_DEFINE (scm_procedure_p, "procedure?", 1, 0, 0,
break; break;
case scm_tcs_closures: case scm_tcs_closures:
case scm_tcs_subrs: case scm_tcs_subrs:
#ifdef CCLO
case scm_tc7_cclo:
#endif
case scm_tc7_pws: case scm_tc7_pws:
return SCM_BOOL_T; return SCM_BOOL_T;
case scm_tc7_smob: case scm_tc7_smob:
@ -179,10 +143,9 @@ SCM_DEFINE (scm_thunk_p, "thunk?", 1, 0, 0,
case scm_tc7_lsubr: case scm_tc7_lsubr:
case scm_tc7_rpsubr: case scm_tc7_rpsubr:
case scm_tc7_asubr: case scm_tc7_asubr:
#ifdef CCLO
case scm_tc7_cclo:
#endif
return SCM_BOOL_T; return SCM_BOOL_T;
case scm_tc7_gsubr:
return scm_from_bool (SCM_GSUBR_REQ (SCM_GSUBR_TYPE (obj)) == 0);
case scm_tc7_pws: case scm_tc7_pws:
obj = SCM_PROCEDURE (obj); obj = SCM_PROCEDURE (obj);
goto again; goto again;
@ -235,12 +198,6 @@ SCM_DEFINE (scm_procedure_documentation, "procedure-documentation", 1, 0, 0,
return SCM_BOOL_F; return SCM_BOOL_F;
default: default:
return SCM_BOOL_F; return SCM_BOOL_F;
/*
case scm_tcs_subrs:
#ifdef CCLO
case scm_tc7_cclo:
#endif
*/
} }
} }
#undef FUNC_NAME #undef FUNC_NAME

View file

@ -40,18 +40,6 @@
#define SCM_SET_SUBR_GENERIC(x, g) (*((SCM *) SCM_CELL_WORD_2 (x)) = (g)) #define SCM_SET_SUBR_GENERIC(x, g) (*((SCM *) SCM_CELL_WORD_2 (x)) = (g))
#define SCM_SET_SUBR_GENERIC_LOC(x, g) (SCM_SET_CELL_WORD_2 (x, (scm_t_bits) g)) #define SCM_SET_SUBR_GENERIC_LOC(x, g) (SCM_SET_CELL_WORD_2 (x, (scm_t_bits) g))
#define SCM_CCLO_LENGTH(x) (SCM_CELL_WORD_0 (x) >> 8)
#define SCM_MAKE_CCLO_TAG(v) (((v) << 8) + scm_tc7_cclo)
#define SCM_SET_CCLO_LENGTH(x, v) (SCM_SET_CELL_WORD_0 ((x), SCM_MAKE_CCLO_TAG(v)))
#define SCM_CCLO_BASE(x) ((scm_t_bits *) SCM_CELL_WORD_1 (x))
#define SCM_SET_CCLO_BASE(x, v) (SCM_SET_CELL_WORD_1 ((x), (v)))
#define SCM_CCLO_REF(x, i) (SCM_PACK (SCM_CCLO_BASE (x) [i]))
#define SCM_CCLO_SET(x, i, v) (SCM_CCLO_BASE (x) [i] = SCM_UNPACK (v))
#define SCM_CCLO_SUBR(x) (SCM_CCLO_REF ((x), 0))
#define SCM_SET_CCLO_SUBR(x, v) (SCM_CCLO_SET ((x), 0, (v)))
/* Closures /* Closures
*/ */
@ -129,7 +117,6 @@ SCM_API SCM scm_c_make_subr_with_generic (const char *name, long type,
SCM_API SCM scm_c_define_subr (const char *name, long type, SCM (*fcn)()); SCM_API SCM scm_c_define_subr (const char *name, long type, SCM (*fcn)());
SCM_API SCM scm_c_define_subr_with_generic (const char *name, long type, SCM_API SCM scm_c_define_subr_with_generic (const char *name, long type,
SCM (*fcn)(), SCM *gf); SCM (*fcn)(), SCM *gf);
SCM_API SCM scm_makcclo (SCM proc, size_t len);
SCM_API SCM scm_procedure_p (SCM obj); SCM_API SCM scm_procedure_p (SCM obj);
SCM_API SCM scm_closure_p (SCM obj); SCM_API SCM scm_closure_p (SCM obj);
SCM_API SCM scm_thunk_p (SCM obj); SCM_API SCM scm_thunk_p (SCM obj);
@ -141,10 +128,6 @@ SCM_API SCM scm_procedure (SCM proc);
SCM_API SCM scm_setter (SCM proc); SCM_API SCM scm_setter (SCM proc);
SCM_INTERNAL void scm_init_procs (void); SCM_INTERNAL void scm_init_procs (void);
#ifdef GUILE_DEBUG
SCM_API SCM scm_make_cclo (SCM proc, SCM len);
#endif /*GUILE_DEBUG*/
#endif /* SCM_PROCS_H */ #endif /* SCM_PROCS_H */
/* /*

View file

@ -1,5 +1,5 @@
/* Representation of stack frame debug information /* Representation of stack frame debug information
* Copyright (C) 1996,1997,2000,2001, 2006, 2007, 2008 Free Software Foundation * Copyright (C) 1996,1997,2000,2001, 2006, 2007, 2008, 2009 Free Software Foundation
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -174,9 +174,6 @@ stack_depth (scm_t_debug_frame *dframe, scm_t_ptrdiff offset, SCM vmframe,
} }
} }
} }
else if (scm_is_eq (vect[0].a.proc, scm_f_gsubr_apply))
/* Skip gsubr apply frames. */
continue;
else else
++n; /* increment for non-program apply frame */ ++n; /* increment for non-program apply frame */
} }
@ -321,9 +318,6 @@ read_frames (scm_t_debug_frame *dframe, scm_t_ptrdiff offset,
NEXT_FRAME (iframe, n, quit); NEXT_FRAME (iframe, n, quit);
} }
} }
else if (scm_is_eq (iframe->proc, scm_f_gsubr_apply))
/* Skip gsubr apply frames. */
continue;
else if (SCM_PROGRAM_P (iframe->proc)) else if (SCM_PROGRAM_P (iframe->proc))
{ {
if (!SCM_PROGRAM_IS_BOOT (iframe->proc)) if (!SCM_PROGRAM_IS_BOOT (iframe->proc))

View file

@ -455,7 +455,7 @@ typedef unsigned long scm_t_bits;
#define scm_tc7_unused_9 79 #define scm_tc7_unused_9 79
#define scm_tc7_dsubr 61 #define scm_tc7_dsubr 61
#define scm_tc7_cclo 63 #define scm_tc7_gsubr 63
#define scm_tc7_rpsubr 69 #define scm_tc7_rpsubr 69
#define scm_tc7_subr_0 85 #define scm_tc7_subr_0 85
#define scm_tc7_subr_1 87 #define scm_tc7_subr_1 87
@ -677,7 +677,8 @@ enum scm_tc8_tags
case scm_tc7_subr_1o:\ case scm_tc7_subr_1o:\
case scm_tc7_subr_2o:\ case scm_tc7_subr_2o:\
case scm_tc7_lsubr_2:\ case scm_tc7_lsubr_2:\
case scm_tc7_lsubr case scm_tc7_lsubr: \
case scm_tc7_gsubr

View file

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in. ## Process this file with automake to produce Makefile.in.
## ##
## Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Software Foundation, Inc. ## Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Software Foundation, Inc.
## ##
## This file is part of GUILE. ## This file is part of GUILE.
## ##
@ -54,6 +54,7 @@ SCM_TESTS = tests/alist.test \
tests/numbers.test \ tests/numbers.test \
tests/optargs.test \ tests/optargs.test \
tests/options.test \ tests/options.test \
tests/procprop.test \
tests/poe.test \ tests/poe.test \
tests/popen.test \ tests/popen.test \
tests/ports.test \ tests/ports.test \

View file

@ -1,5 +1,5 @@
;;;; eval.test --- tests guile's evaluator -*- scheme -*- ;;;; eval.test --- tests guile's evaluator -*- scheme -*-
;;;; Copyright (C) 2000, 2001, 2006, 2007 Free Software Foundation, Inc. ;;;; Copyright (C) 2000, 2001, 2006, 2007, 2009 Free Software Foundation, Inc.
;;;; ;;;;
;;;; This library is free software; you can redistribute it and/or ;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public ;;;; modify it under the terms of the GNU Lesser General Public
@ -17,6 +17,7 @@
(define-module (test-suite test-eval) (define-module (test-suite test-eval)
:use-module (test-suite lib) :use-module (test-suite lib)
:use-module ((srfi srfi-1) :select (unfold count))
:use-module (ice-9 documentation)) :use-module (ice-9 documentation))
@ -316,6 +317,68 @@
(%make-void-port "w")) (%make-void-port "w"))
#t)))) #t))))
;;;
;;; stacks
;;;
(define (stack->frames stack)
;; Return the list of frames comprising STACK.
(unfold (lambda (i)
(>= i (stack-length stack)))
(lambda (i)
(stack-ref stack i))
1+
0))
(with-test-prefix "stacks"
(with-debugging-evaluator
(pass-if "stack involving a subr"
;; The subr involving the error must appear exactly once on the stack.
(catch 'result
(lambda ()
(start-stack 'foo
(lazy-catch 'wrong-type-arg
(lambda ()
;; Trigger a `wrong-type-arg' exception.
(fluid-ref 'not-a-fluid))
(lambda _
(let* ((stack (make-stack #t))
(frames (stack->frames stack)))
(throw 'result
(count (lambda (frame)
(and (frame-procedure? frame)
(eq? (frame-procedure frame)
fluid-ref)))
frames)))))))
(lambda (key result)
(= 1 result))))
(pass-if "stack involving a gsubr"
;; The gsubr involving the error must appear exactly once on the stack.
;; This is less obvious since gsubr application may require an
;; additional `SCM_APPLY ()' call, which should not be visible to the
;; application.
(catch 'result
(lambda ()
(start-stack 'foo
(lazy-catch 'wrong-type-arg
(lambda ()
;; Trigger a `wrong-type-arg' exception.
(hashq-ref 'wrong 'type 'arg))
(lambda _
(let* ((stack (make-stack #t))
(frames (stack->frames stack)))
(throw 'result
(count (lambda (frame)
(and (frame-procedure? frame)
(eq? (frame-procedure frame)
hashq-ref)))
frames)))))))
(lambda (key result)
(= 1 result))))))
;;; ;;;
;;; letrec init evaluation ;;; letrec init evaluation
;;; ;;;

View file

@ -1,6 +1,6 @@
;;;; goops.test --- test suite for GOOPS -*- scheme -*- ;;;; goops.test --- test suite for GOOPS -*- scheme -*-
;;;; ;;;;
;;;; Copyright (C) 2001,2003,2004, 2006, 2008 Free Software Foundation, Inc. ;;;; Copyright (C) 2001,2003,2004, 2006, 2008, 2009 Free Software Foundation, Inc.
;;;; ;;;;
;;;; This program is free software; you can redistribute it and/or modify ;;;; This program is free software; you can redistribute it and/or modify
;;;; it under the terms of the GNU General Public License as published by ;;;; it under the terms of the GNU General Public License as published by
@ -125,6 +125,24 @@
table)))) table))))
) )
(with-test-prefix "classes for built-in types"
(pass-if "subr"
(eq? (class-of fluid-ref) <procedure>))
(pass-if "gsubr"
(eq? (class-of hashq-ref) <procedure>))
(pass-if "car"
(eq? (class-of car) <procedure>))
(pass-if "string"
(eq? (class-of "foo") <string>))
(pass-if "port"
(is-a? (%make-void-port "w") <port>)))
(with-test-prefix "defining classes" (with-test-prefix "defining classes"
(with-test-prefix "define-class" (with-test-prefix "define-class"

View file

@ -0,0 +1,61 @@
;;;; procprop.test --- Procedure properties -*- Scheme -*-
;;;; Ludovic Courtès <ludo@gnu.org>
;;;;
;;;; Copyright (C) 2009 Free Software Foundation, Inc.
;;;;
;;;; This program is free software; you can redistribute it and/or modify
;;;; it under the terms of the GNU General Public License as published by
;;;; the Free Software Foundation; either version 2, or (at your option)
;;;; any later version.
;;;;
;;;; This program is distributed in the hope that it will be useful,
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;;; GNU General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU General Public License
;;;; along with this software; see the file COPYING. If not, write to
;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;;;; Boston, MA 02110-1301 USA
(define-module (test-procpop)
:use-module (test-suite lib))
(with-test-prefix "procedure-name"
(pass-if "simple subr"
(eq? 'display (procedure-name display)))
(pass-if "gsubr"
(eq? 'hashq-ref (procedure-name hashq-ref))))
(with-test-prefix "procedure-arity"
(pass-if "simple subr"
(equal? (procedure-property display 'arity)
'(1 1 #f)))
(pass-if "gsubr"
(equal? (procedure-property hashq-ref 'arity)
'(2 1 #f)))
(pass-if "port-closed?"
(equal? (procedure-property port-closed? 'arity)
'(1 0 #f)))
(pass-if "apply"
(equal? (procedure-property apply 'arity)
'(1 0 #t)))
(pass-if "cons*"
(equal? (procedure-property cons* 'arity)
'(1 0 #t)))
(pass-if "list"
(equal? (procedure-property list 'arity)
'(0 0 #t))))
;;; Local Variables:
;;; coding: latin-1
;;; End: