summaryrefslogtreecommitdiff
path: root/libguile/pairs.h
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/pairs.h')
-rw-r--r--libguile/pairs.h66
1 files changed, 62 insertions, 4 deletions
diff --git a/libguile/pairs.h b/libguile/pairs.h
index 6edfc9c3e..130bf28a6 100644
--- a/libguile/pairs.h
+++ b/libguile/pairs.h
@@ -3,7 +3,7 @@
#ifndef SCM_PAIRS_H
#define SCM_PAIRS_H
-/* Copyright (C) 1995,1996,2000,2001, 2004, 2006, 2008, 2009, 2010 Free Software Foundation, Inc.
+/* Copyright (C) 1995,1996,2000,2001, 2004, 2006, 2008, 2009, 2010, 2012 Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -25,6 +25,8 @@
#include "libguile/__scm.h"
+#include "libguile/gc.h"
+
#if (SCM_DEBUG_PAIR_ACCESSES == 1)
@@ -115,11 +117,67 @@
SCM_API void scm_error_pair_access (SCM);
#endif
-SCM_API SCM scm_cons (SCM x, SCM y);
+SCM_INLINE int scm_is_pair (SCM x);
+SCM_INLINE SCM scm_cons (SCM x, SCM y);
+SCM_INLINE SCM scm_car (SCM x);
+SCM_INLINE SCM scm_cdr (SCM x);
+
+#if SCM_CAN_INLINE || defined SCM_INLINE_C_IMPLEMENTING_INLINES
+/* Return a newly allocated pair whose car is @var{x} and whose cdr is
+ @var{y}. The pair is guaranteed to be different (in the sense of
+ @code{eq?}) from every previously existing object. */
+SCM_INLINE_IMPLEMENTATION SCM
+scm_cons (SCM x, SCM y)
+{
+ return scm_cell (SCM_UNPACK (x), SCM_UNPACK (y));
+}
+
+SCM_INLINE_IMPLEMENTATION int
+scm_is_pair (SCM x)
+{
+ /* The following "workaround_for_gcc_295" avoids bad code generated by
+ i386 gcc 2.95.4 (the Debian packaged 2.95.4-24 at least).
+
+ Under the default -O2 the inlined SCM_I_CONSP test gets "optimized" so
+ the fetch of the tag word from x is done before confirming it's a
+ non-immediate (SCM_NIMP). Needless to say that bombs badly if x is a
+ immediate. This was seen to afflict scm_srfi1_split_at and something
+ deep in the bowels of ceval(). In both cases segvs resulted from
+ deferencing a random immediate value. srfi-1.test exposes the problem
+ through a short list, the immediate being SCM_EOL in that case.
+ Something in syntax.test exposed the ceval() problem.
+
+ Just "volatile SCM workaround_for_gcc_295 = lst" is enough to avoid the
+ problem, without even using that variable. The "w=w" is just to
+ prevent a warning about it being unused.
+ */
+#if defined (__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ == 95
+ volatile SCM workaround_for_gcc_295 = x;
+ workaround_for_gcc_295 = workaround_for_gcc_295;
+#endif
+
+ return SCM_I_CONSP (x);
+}
+
+SCM_INLINE_IMPLEMENTATION SCM
+scm_car (SCM x)
+{
+ if (SCM_UNLIKELY (!scm_is_pair (x)))
+ scm_wrong_type_arg_msg ("car", 0, x, "pair");
+ return SCM_CAR (x);
+}
+
+SCM_INLINE_IMPLEMENTATION SCM
+scm_cdr (SCM x)
+{
+ if (SCM_UNLIKELY (!scm_is_pair (x)))
+ scm_wrong_type_arg_msg ("cdr", 0, x, "pair");
+ return SCM_CDR (x);
+}
+#endif
+
SCM_API SCM scm_cons2 (SCM w, SCM x, SCM y);
SCM_API SCM scm_pair_p (SCM x);
-SCM_API SCM scm_car (SCM x);
-SCM_API SCM scm_cdr (SCM x);
SCM_API SCM scm_set_car_x (SCM pair, SCM value);
SCM_API SCM scm_set_cdr_x (SCM pair, SCM value);