2018-06-20 19:17:06 +02:00
|
|
|
|
/* Copyright 1995-1996,1998,2000-2001,2003,2006,2008-2014,2018
|
2018-06-20 20:01:49 +02:00
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
|
|
|
|
This file is part of Guile.
|
|
|
|
|
|
|
|
|
|
|
|
Guile is free software: you can redistribute it and/or modify it
|
|
|
|
|
|
under the terms of the GNU Lesser General Public License as published
|
|
|
|
|
|
by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
|
|
Guile 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 Lesser General Public
|
|
|
|
|
|
License for more details.
|
|
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
License along with Guile. If not, see
|
|
|
|
|
|
<https://www.gnu.org/licenses/>. */
|
2011-10-24 10:52:55 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
|
# include <config.h>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2018-06-19 11:48:09 +02:00
|
|
|
|
#include <string.h>
|
2011-10-24 10:52:55 +02:00
|
|
|
|
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "boolean.h"
|
|
|
|
|
|
#include "extensions.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "gsubr.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "list.h"
|
|
|
|
|
|
#include "pairs.h"
|
|
|
|
|
|
#include "vectors.h"
|
2018-10-07 15:15:02 +02:00
|
|
|
|
#include "version.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "weak-vector.h"
|
2011-10-24 10:52:55 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* {Weak Vectors}
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#define VECTOR_MAX_LENGTH (SCM_T_BITS_MAX >> 8)
|
|
|
|
|
|
|
2014-02-07 13:00:12 +01:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_c_make_weak_vector (size_t len, SCM fill)
|
2011-10-24 10:52:55 +02:00
|
|
|
|
#define FUNC_NAME "make-weak-vector"
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM wv;
|
|
|
|
|
|
size_t j;
|
|
|
|
|
|
|
|
|
|
|
|
SCM_ASSERT_RANGE (1, scm_from_size_t (len), len <= VECTOR_MAX_LENGTH);
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_UNBNDP (fill))
|
|
|
|
|
|
fill = SCM_UNSPECIFIED;
|
|
|
|
|
|
|
2011-10-24 17:58:22 +02:00
|
|
|
|
wv = SCM_PACK_POINTER (scm_gc_malloc_pointerless ((len + 1) * sizeof (SCM),
|
2011-10-24 10:52:55 +02:00
|
|
|
|
"weak vector"));
|
|
|
|
|
|
|
|
|
|
|
|
SCM_SET_CELL_WORD_0 (wv, (len << 8) | scm_tc7_wvect);
|
|
|
|
|
|
|
2011-10-24 18:13:51 +02:00
|
|
|
|
if (SCM_HEAP_OBJECT_P (fill))
|
2011-10-24 10:52:55 +02:00
|
|
|
|
{
|
|
|
|
|
|
memset (SCM_I_VECTOR_WELTS (wv), 0, len * sizeof (SCM));
|
|
|
|
|
|
for (j = 0; j < len; j++)
|
|
|
|
|
|
scm_c_weak_vector_set_x (wv, j, fill);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
for (j = 0; j < len; j++)
|
|
|
|
|
|
SCM_SIMPLE_VECTOR_SET (wv, j, fill);
|
|
|
|
|
|
|
|
|
|
|
|
return wv;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_make_weak_vector, "make-weak-vector", 1, 1, 0,
|
|
|
|
|
|
(SCM size, SCM fill),
|
|
|
|
|
|
"Return a weak vector with @var{size} elements. If the optional\n"
|
|
|
|
|
|
"argument @var{fill} is given, all entries in the vector will be\n"
|
|
|
|
|
|
"set to @var{fill}. The default value for @var{fill} is the\n"
|
|
|
|
|
|
"empty list.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_make_weak_vector
|
|
|
|
|
|
{
|
2014-02-07 13:00:12 +01:00
|
|
|
|
return scm_c_make_weak_vector (scm_to_size_t (size), fill);
|
2011-10-24 10:52:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_REGISTER_PROC(s_list_to_weak_vector, "list->weak-vector", 1, 0, 0, scm_weak_vector);
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_weak_vector, "weak-vector", 0, 0, 1,
|
|
|
|
|
|
(SCM lst),
|
|
|
|
|
|
"@deffnx {Scheme Procedure} list->weak-vector lst\n"
|
|
|
|
|
|
"Construct a weak vector from a list: @code{weak-vector} uses\n"
|
|
|
|
|
|
"the list of its arguments while @code{list->weak-vector} uses\n"
|
|
|
|
|
|
"its only argument @var{l} (a list) to construct a weak vector\n"
|
|
|
|
|
|
"the same way @code{list->vector} would.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_weak_vector
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM wv;
|
|
|
|
|
|
size_t i;
|
|
|
|
|
|
long c_size;
|
|
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_LIST_COPYLEN (SCM_ARG1, lst, c_size);
|
|
|
|
|
|
|
2014-02-07 13:00:12 +01:00
|
|
|
|
wv = scm_c_make_weak_vector ((size_t) c_size, SCM_BOOL_F);
|
2011-10-24 10:52:55 +02:00
|
|
|
|
|
|
|
|
|
|
for (i = 0; scm_is_pair (lst); lst = SCM_CDR (lst), i++)
|
|
|
|
|
|
scm_c_weak_vector_set_x (wv, i, SCM_CAR (lst));
|
|
|
|
|
|
|
|
|
|
|
|
return wv;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_weak_vector_p, "weak-vector?", 1, 0, 0,
|
|
|
|
|
|
(SCM obj),
|
|
|
|
|
|
"Return @code{#t} if @var{obj} is a weak vector. Note that all\n"
|
|
|
|
|
|
"weak hashes are also weak vectors.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_weak_vector_p
|
|
|
|
|
|
{
|
2014-02-07 13:00:12 +01:00
|
|
|
|
return scm_from_bool (scm_is_weak_vector (obj));
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
|
scm_is_weak_vector (SCM obj)
|
|
|
|
|
|
#define FUNC_NAME s_scm_weak_vector_p
|
|
|
|
|
|
{
|
|
|
|
|
|
return SCM_I_WVECTP (obj);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define SCM_VALIDATE_WEAK_VECTOR(pos, var) \
|
|
|
|
|
|
SCM_I_MAKE_VALIDATE_MSG2 (pos, var, SCM_I_WVECTP, "weak vector")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_weak_vector_length, "weak-vector-length", 1, 0, 0,
|
|
|
|
|
|
(SCM wvect),
|
|
|
|
|
|
"Like @code{vector-length}, but for weak vectors.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_weak_vector_length
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_from_size_t (scm_c_weak_vector_length (wvect));
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size_t
|
|
|
|
|
|
scm_c_weak_vector_length (SCM wvect)
|
|
|
|
|
|
#define FUNC_NAME s_scm_weak_vector_length
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_WEAK_VECTOR (1, wvect);
|
|
|
|
|
|
return SCM_I_VECTOR_LENGTH (wvect);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_weak_vector_ref, "weak-vector-ref", 2, 0, 0,
|
|
|
|
|
|
(SCM wvect, SCM k),
|
|
|
|
|
|
"Like @code{vector-ref}, but for weak vectors.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_weak_vector_ref
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_c_weak_vector_ref (wvect, scm_to_size_t (k));
|
2011-10-24 10:52:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct weak_vector_ref_data
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM wv;
|
|
|
|
|
|
size_t k;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void*
|
|
|
|
|
|
weak_vector_ref (void *data)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct weak_vector_ref_data *d = data;
|
|
|
|
|
|
|
2013-08-08 01:23:04 -04:00
|
|
|
|
return (void *) SCM_UNPACK (SCM_SIMPLE_VECTOR_REF (d->wv, d->k));
|
2011-10-24 10:52:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_c_weak_vector_ref (SCM wv, size_t k)
|
2014-02-07 13:00:12 +01:00
|
|
|
|
#define FUNC_NAME s_scm_weak_vector_ref
|
2011-10-24 10:52:55 +02:00
|
|
|
|
{
|
|
|
|
|
|
struct weak_vector_ref_data d;
|
|
|
|
|
|
void *ret;
|
|
|
|
|
|
|
2014-02-07 13:00:12 +01:00
|
|
|
|
SCM_VALIDATE_WEAK_VECTOR (1, wv);
|
|
|
|
|
|
|
2011-10-24 10:52:55 +02:00
|
|
|
|
d.wv = wv;
|
|
|
|
|
|
d.k = k;
|
|
|
|
|
|
|
|
|
|
|
|
if (k >= SCM_I_VECTOR_LENGTH (wv))
|
2014-02-08 14:48:48 +01:00
|
|
|
|
scm_out_of_range ("weak-vector-ref", scm_from_size_t (k));
|
2011-10-24 10:52:55 +02:00
|
|
|
|
|
|
|
|
|
|
ret = GC_call_with_alloc_lock (weak_vector_ref, &d);
|
|
|
|
|
|
|
|
|
|
|
|
if (ret)
|
2011-10-24 17:58:22 +02:00
|
|
|
|
return SCM_PACK_POINTER (ret);
|
2011-10-24 10:52:55 +02:00
|
|
|
|
else
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
}
|
2014-02-07 13:00:12 +01:00
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_weak_vector_set_x, "weak-vector-set!", 3, 0, 0,
|
|
|
|
|
|
(SCM wvect, SCM k, SCM obj),
|
|
|
|
|
|
"Like @code{vector-set!}, but for weak vectors.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_weak_vector_set_x
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_c_weak_vector_set_x (wvect, scm_to_size_t (k), obj);
|
|
|
|
|
|
|
|
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
2011-10-24 10:52:55 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_c_weak_vector_set_x (SCM wv, size_t k, SCM x)
|
2014-02-07 13:00:12 +01:00
|
|
|
|
#define FUNC_NAME s_scm_weak_vector_set_x
|
2011-10-24 10:52:55 +02:00
|
|
|
|
{
|
|
|
|
|
|
SCM *elts;
|
|
|
|
|
|
struct weak_vector_ref_data d;
|
|
|
|
|
|
void *prev;
|
|
|
|
|
|
|
2014-02-07 13:00:12 +01:00
|
|
|
|
SCM_VALIDATE_WEAK_VECTOR (1, wv);
|
|
|
|
|
|
|
2011-10-24 10:52:55 +02:00
|
|
|
|
d.wv = wv;
|
|
|
|
|
|
d.k = k;
|
|
|
|
|
|
|
|
|
|
|
|
if (k >= SCM_I_VECTOR_LENGTH (wv))
|
2014-02-08 14:48:48 +01:00
|
|
|
|
scm_out_of_range ("weak-vector-set!", scm_from_size_t (k));
|
2011-10-24 10:52:55 +02:00
|
|
|
|
|
|
|
|
|
|
prev = GC_call_with_alloc_lock (weak_vector_ref, &d);
|
|
|
|
|
|
|
|
|
|
|
|
elts = SCM_I_VECTOR_WELTS (wv);
|
|
|
|
|
|
|
2011-10-24 18:13:51 +02:00
|
|
|
|
if (prev && SCM_HEAP_OBJECT_P (SCM_PACK_POINTER (prev)))
|
2012-07-06 16:52:54 +02:00
|
|
|
|
GC_unregister_disappearing_link ((void **) &elts[k]);
|
2011-10-24 10:52:55 +02:00
|
|
|
|
|
|
|
|
|
|
elts[k] = x;
|
|
|
|
|
|
|
2011-10-24 18:13:51 +02:00
|
|
|
|
if (SCM_HEAP_OBJECT_P (x))
|
2012-07-06 16:52:54 +02:00
|
|
|
|
SCM_I_REGISTER_DISAPPEARING_LINK ((void **) &elts[k],
|
|
|
|
|
|
SCM2PTR (x));
|
2011-10-24 10:52:55 +02:00
|
|
|
|
}
|
2014-02-07 13:00:12 +01:00
|
|
|
|
#undef FUNC_NAME
|
2011-10-24 10:52:55 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
scm_init_weak_vector_builtins (void)
|
|
|
|
|
|
{
|
|
|
|
|
|
#ifndef SCM_MAGIC_SNARFER
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "weak-vector.x"
|
2011-10-24 10:52:55 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_init_weak_vectors ()
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
|
|
|
|
|
|
"scm_init_weak_vector_builtins",
|
|
|
|
|
|
(scm_t_extension_init_func)scm_init_weak_vector_builtins,
|
|
|
|
|
|
NULL);
|
|
|
|
|
|
}
|
|
|
|
|
|
|