Merge.
This commit is contained in:
commit
2019f2c12d
33 changed files with 393 additions and 231 deletions
|
|
@ -14,6 +14,7 @@
|
||||||
(eval . (put 'with-test-prefix/c&e 'scheme-indent-function 1))
|
(eval . (put 'with-test-prefix/c&e 'scheme-indent-function 1))
|
||||||
(eval . (put 'with-code-coverage 'scheme-indent-function 1))
|
(eval . (put 'with-code-coverage 'scheme-indent-function 1))
|
||||||
(eval . (put 'with-statprof 'scheme-indent-function 1))
|
(eval . (put 'with-statprof 'scheme-indent-function 1))
|
||||||
|
(eval . (put 'with-target 'scheme-indent-function 1))
|
||||||
(eval . (put 'let-gensyms 'scheme-indent-function 1))
|
(eval . (put 'let-gensyms 'scheme-indent-function 1))
|
||||||
(eval . (put 'let-fresh 'scheme-indent-function 2))
|
(eval . (put 'let-fresh 'scheme-indent-function 2))
|
||||||
(eval . (put 'with-fresh-name-state 'scheme-indent-function 1))
|
(eval . (put 'with-fresh-name-state 'scheme-indent-function 1))
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
# Note: `GUILE_VERSION' is defined in `configure.ac' using `git-version-gen'.
|
# Note: `GUILE_VERSION' is defined in `configure.ac' using `git-version-gen'.
|
||||||
GUILE_MAJOR_VERSION=3
|
GUILE_MAJOR_VERSION=3
|
||||||
GUILE_MINOR_VERSION=0
|
GUILE_MINOR_VERSION=0
|
||||||
GUILE_MICRO_VERSION=2
|
GUILE_MICRO_VERSION=4
|
||||||
|
|
||||||
GUILE_EFFECTIVE_VERSION=3.0
|
GUILE_EFFECTIVE_VERSION=3.0
|
||||||
|
|
||||||
|
|
@ -14,9 +14,10 @@ GUILE_EFFECTIVE_VERSION=3.0
|
||||||
# Makefile.am.
|
# Makefile.am.
|
||||||
|
|
||||||
# See libtool info pages for more information on how and when to
|
# See libtool info pages for more information on how and when to
|
||||||
# change these.
|
# change these. Note: We consider the ABI of default builds, and not
|
||||||
|
# that of '--disable-deprecated' builds.
|
||||||
|
|
||||||
LIBGUILE_INTERFACE_CURRENT=2
|
LIBGUILE_INTERFACE_CURRENT=3
|
||||||
LIBGUILE_INTERFACE_REVISION=1
|
LIBGUILE_INTERFACE_REVISION=0
|
||||||
LIBGUILE_INTERFACE_AGE=1
|
LIBGUILE_INTERFACE_AGE=2
|
||||||
LIBGUILE_INTERFACE="${LIBGUILE_INTERFACE_CURRENT}:${LIBGUILE_INTERFACE_REVISION}:${LIBGUILE_INTERFACE_AGE}"
|
LIBGUILE_INTERFACE="${LIBGUILE_INTERFACE_CURRENT}:${LIBGUILE_INTERFACE_REVISION}:${LIBGUILE_INTERFACE_AGE}"
|
||||||
|
|
|
||||||
43
NEWS
43
NEWS
|
|
@ -4,6 +4,15 @@ 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.
|
||||||
|
|
||||||
|
|
||||||
|
Changes in 3.0.4 (since 3.0.3)
|
||||||
|
|
||||||
|
This release fixes the SONAME of libguile-3.0.so, which was erroneously
|
||||||
|
bumped in 3.0.3 compared to 3.0.2. Distributions are strongly
|
||||||
|
encouraged to use 3.0.4 instead of 3.0.3.
|
||||||
|
|
||||||
|
Thanks to Chris Vine for reporting the issue.
|
||||||
|
|
||||||
|
|
||||||
Changes in 3.0.3 (since 3.0.2)
|
Changes in 3.0.3 (since 3.0.2)
|
||||||
|
|
||||||
|
|
@ -45,6 +54,11 @@ the first Scheme compiler. Because the baseline compiler runs faster
|
||||||
and includes less code than the CPS compiler, Guile takes less time to
|
and includes less code than the CPS compiler, Guile takes less time to
|
||||||
build.
|
build.
|
||||||
|
|
||||||
|
** New 'pipeline' procedure in (ice-9 popen)
|
||||||
|
|
||||||
|
The 'pipeline' procedure provides a simple way to spawn command pipeline
|
||||||
|
as one would do in a shell.
|
||||||
|
|
||||||
** Refreshed bitvector facility
|
** Refreshed bitvector facility
|
||||||
|
|
||||||
See "Bit Vectors" in the manual, for more on all of these.
|
See "Bit Vectors" in the manual, for more on all of these.
|
||||||
|
|
@ -80,6 +94,35 @@ This replaces bit-invert!.
|
||||||
|
|
||||||
These replace the wonky "bit-set*!" procedure.
|
These replace the wonky "bit-set*!" procedure.
|
||||||
|
|
||||||
|
* Bug fixes
|
||||||
|
|
||||||
|
** statprof reports the names of primitives
|
||||||
|
|
||||||
|
Previously statprof would show strings like "anon #x1234" for primitives
|
||||||
|
written in C.
|
||||||
|
|
||||||
|
** Compiler reduces 'equal?' when passed a character literal
|
||||||
|
|
||||||
|
The compiler now properly reduces expressions such as (equal? c #\x) to
|
||||||
|
(eq? c #\x). This was not the case in 3.0.2, which could lead to slower
|
||||||
|
code, especially in 'match' expressions with many clauses with with
|
||||||
|
character literals.
|
||||||
|
|
||||||
|
** JIT bugs on ARMv7 have been fixed
|
||||||
|
(<https://bugs.gnu.org/40737>,
|
||||||
|
<https://gitlab.com/wingo/lightening/-/issues/12>)
|
||||||
|
|
||||||
|
** 'http-get', 'http-post', etc. now honor #:verify-certificates?
|
||||||
|
(<https://bugs.gnu.org/40486>)
|
||||||
|
|
||||||
|
** web: Accept URI host names consisting only of hex digits
|
||||||
|
(<https://bugs.gnu.org/40582>)
|
||||||
|
|
||||||
|
** (web http) parser recognizes the CONNECT and PATCH methods
|
||||||
|
|
||||||
|
** Initial revealed count of file ports is now zero
|
||||||
|
(<https://bugs.gnu.org/41204>)
|
||||||
|
|
||||||
* New deprecations
|
* New deprecations
|
||||||
|
|
||||||
** Old bitvector interfaces deprecated
|
** Old bitvector interfaces deprecated
|
||||||
|
|
|
||||||
|
|
@ -3183,9 +3183,10 @@ produce the corresponding string element. The order in which
|
||||||
@deffnx {C Function} scm_string_join (ls, delimiter, grammar)
|
@deffnx {C Function} scm_string_join (ls, delimiter, grammar)
|
||||||
Append the string in the string list @var{ls}, using the string
|
Append the string in the string list @var{ls}, using the string
|
||||||
@var{delimiter} as a delimiter between the elements of @var{ls}.
|
@var{delimiter} as a delimiter between the elements of @var{ls}.
|
||||||
@var{grammar} is a symbol which specifies how the delimiter is
|
@var{delimiter} defaults to @w{@samp{ }}, that is, strings in @var{ls}
|
||||||
placed between the strings, and defaults to the symbol
|
are appended with the space character in between them. @var{grammar} is
|
||||||
@code{infix}.
|
a symbol which specifies how the delimiter is placed between the
|
||||||
|
strings, and defaults to the symbol @code{infix}.
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item infix
|
@item infix
|
||||||
|
|
|
||||||
|
|
@ -1596,7 +1596,7 @@ of bytes read.
|
||||||
|
|
||||||
@item write
|
@item write
|
||||||
A port's @code{write} implementation flushes write buffers to the
|
A port's @code{write} implementation flushes write buffers to the
|
||||||
mutable store. A port's @code{read} implementation fills read buffers.
|
mutable store.
|
||||||
It should write out bytes from the supplied bytevector @code{src},
|
It should write out bytes from the supplied bytevector @code{src},
|
||||||
starting at offset @code{start} and continuing for @code{count} bytes,
|
starting at offset @code{start} and continuing for @code{count} bytes,
|
||||||
and return the number of bytes that were written.
|
and return the number of bytes that were written.
|
||||||
|
|
|
||||||
|
|
@ -1040,6 +1040,21 @@ If @var{suffix} is provided, and is equal to the end of
|
||||||
@end lisp
|
@end lisp
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} canonicalize-path path
|
||||||
|
@deffnx {C Function} scm_canonicalize_path (path)
|
||||||
|
Return the canonical (absolute) path of @var{path}.
|
||||||
|
A canonical path has no @code{.} or @code{..} components,
|
||||||
|
nor any repeated path separators (@code{/}) nor symlinks.
|
||||||
|
|
||||||
|
Raises an error if any component of @var{path} does not
|
||||||
|
exist.
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(canonicalize-path "test.xml")
|
||||||
|
@result{} "/tmp/test.xml"
|
||||||
|
@end lisp
|
||||||
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} file-exists? filename
|
@deffn {Scheme Procedure} file-exists? filename
|
||||||
Return @code{#t} if the file named @var{filename} exists, @code{#f} if
|
Return @code{#t} if the file named @var{filename} exists, @code{#f} if
|
||||||
not.
|
not.
|
||||||
|
|
|
||||||
|
|
@ -311,6 +311,9 @@ will be printed farther to the right, though if the width of the
|
||||||
indentation passes the @var{max-indent}, the indentation is abbreviated.
|
indentation passes the @var{max-indent}, the indentation is abbreviated.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
These REPL commands can also be called as regular functions in scheme
|
||||||
|
code on including the @code{(ice-9 time)} module.
|
||||||
|
|
||||||
@node Debug Commands
|
@node Debug Commands
|
||||||
@subsubsection Debug Commands
|
@subsubsection Debug Commands
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000-2004, 2006, 2007-2014, 2017, 2018, 2019
|
@c Copyright (C) 1996, 1997, 2000-2004, 2006, 2007-2014, 2017, 2018, 2019, 2020
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
|
@ -824,7 +824,7 @@ predicate or a comparison object for determining which elements are to
|
||||||
be searched.
|
be searched.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} find pred lst
|
@deffn {Scheme Procedure} find pred lst
|
||||||
Return the first element of @var{lst} which satisfies the predicate
|
Return the first element of @var{lst} that satisfies the predicate
|
||||||
@var{pred} and @code{#f} if no such element is found.
|
@var{pred} and @code{#f} if no such element is found.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -772,11 +772,11 @@ The MD5 digest of a resource.
|
||||||
@end deftypevr
|
@end deftypevr
|
||||||
|
|
||||||
@deftypevr {HTTP Header} List content-range
|
@deftypevr {HTTP Header} List content-range
|
||||||
A range specification, as a list of three elements: the symbol
|
Range specification as a list of three elements: the symbol
|
||||||
@code{bytes}, either the symbol @code{*} or a pair of integers,
|
@code{bytes}, either the symbol @code{*} or a pair of integers
|
||||||
indicating the byte rage, and either @code{*} or an integer, for the
|
indicating the byte range, and either @code{*} or an integer indicating
|
||||||
instance length. Used to indicate that a response only includes part of
|
the instance length. Used to indicate that a response only includes
|
||||||
a resource.
|
part of a resource.
|
||||||
@example
|
@example
|
||||||
(parse-header 'content-range "bytes 10-20/*")
|
(parse-header 'content-range "bytes 10-20/*")
|
||||||
@result{} (bytes (10 . 20) *)
|
@result{} (bytes (10 . 20) *)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
image: debian:testing
|
image: debian:stable
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- dpkg --add-architecture i386
|
- dpkg --add-architecture i386
|
||||||
|
|
@ -30,4 +30,9 @@ aarch64:
|
||||||
armhf:
|
armhf:
|
||||||
stage: test
|
stage: test
|
||||||
script:
|
script:
|
||||||
- make -C tests test-armv7 CC_ARMv7=arm-linux-gnueabihf-gcc
|
- make -C tests test-armv7 CC_ARMv7="arm-linux-gnueabihf-gcc -marm"
|
||||||
|
|
||||||
|
armhf-thumb:
|
||||||
|
stage: test
|
||||||
|
script:
|
||||||
|
- make -C tests test-armv7 CC_ARMv7="arm-linux-gnueabihf-gcc -mthumb"
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,8 @@ enum jit_reloc_kind
|
||||||
JIT_RELOC_JCC_WITH_VENEER,
|
JIT_RELOC_JCC_WITH_VENEER,
|
||||||
JIT_RELOC_LOAD_FROM_POOL,
|
JIT_RELOC_LOAD_FROM_POOL,
|
||||||
#endif
|
#endif
|
||||||
|
JIT_RELOC_MASK = 15,
|
||||||
|
JIT_RELOC_FLAG_0 = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct jit_reloc
|
typedef struct jit_reloc
|
||||||
|
|
|
||||||
|
|
@ -90,9 +90,9 @@ DEFINE_ENCODER(size, 2, 22, unsigned, uint32_t)
|
||||||
{ \
|
{ \
|
||||||
return read_signed_bitfield(*loc, kind##_width, kind##_shift); \
|
return read_signed_bitfield(*loc, kind##_width, kind##_shift); \
|
||||||
} \
|
} \
|
||||||
static int offset_in_##name##_range(ptrdiff_t diff) maybe_unused; \
|
static int offset_in_##name##_range(ptrdiff_t diff, int flags) maybe_unused; \
|
||||||
static int \
|
static int \
|
||||||
offset_in_##name##_range(ptrdiff_t diff) \
|
offset_in_##name##_range(ptrdiff_t diff, int flags) \
|
||||||
{ \
|
{ \
|
||||||
return in_signed_range(diff, kind##_width); \
|
return in_signed_range(diff, kind##_width); \
|
||||||
} \
|
} \
|
||||||
|
|
@ -114,8 +114,12 @@ DEFINE_ENCODER(size, 2, 22, unsigned, uint32_t)
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PATCHABLE_INSTRUCTION(jmp, simm26, JMP_WITH_VENEER, 2);
|
#define DEFINE_PATCHABLE_INSTRUCTIONS(name, kind, RELOC, rsh) \
|
||||||
DEFINE_PATCHABLE_INSTRUCTION(jcc, simm19, JCC_WITH_VENEER, 2);
|
DEFINE_PATCHABLE_INSTRUCTION(name, kind, RELOC, rsh); \
|
||||||
|
DEFINE_PATCHABLE_INSTRUCTION(veneer_##name, kind, RELOC, rsh);
|
||||||
|
|
||||||
|
DEFINE_PATCHABLE_INSTRUCTIONS(jmp, simm26, JMP_WITH_VENEER, 2);
|
||||||
|
DEFINE_PATCHABLE_INSTRUCTIONS(jcc, simm19, JCC_WITH_VENEER, 2);
|
||||||
DEFINE_PATCHABLE_INSTRUCTION(load_from_pool, simm19, LOAD_FROM_POOL, 2);
|
DEFINE_PATCHABLE_INSTRUCTION(load_from_pool, simm19, LOAD_FROM_POOL, 2);
|
||||||
|
|
||||||
struct veneer
|
struct veneer
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2012-2017, 2019 Free Software Foundation, Inc.
|
* Copyright (C) 2012-2017,2019-2020 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GNU lightning.
|
* This file is part of GNU lightning.
|
||||||
*
|
*
|
||||||
|
|
@ -186,6 +186,8 @@
|
||||||
|
|
||||||
#define _NOREG (jit_gpr_regno(_PC))
|
#define _NOREG (jit_gpr_regno(_PC))
|
||||||
|
|
||||||
|
#define JIT_RELOC_B JIT_RELOC_FLAG_0
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_wide_thumb(jit_state_t *_jit, uint32_t inst)
|
emit_wide_thumb(jit_state_t *_jit, uint32_t inst)
|
||||||
{
|
{
|
||||||
|
|
@ -193,8 +195,15 @@ emit_wide_thumb(jit_state_t *_jit, uint32_t inst)
|
||||||
emit_u16_with_pool(_jit, inst & 0xffff);
|
emit_u16_with_pool(_jit, inst & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* from binutils */
|
static uint32_t
|
||||||
# define rotate_left(v, n) (v << n | v >> (32 - n))
|
rotate_left(uint32_t v, uint32_t n) {
|
||||||
|
if (n == 0) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
ASSERT(n < 32);
|
||||||
|
return (v << n | v >> (32 - n));
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
encode_arm_immediate(unsigned int v)
|
encode_arm_immediate(unsigned int v)
|
||||||
{
|
{
|
||||||
|
|
@ -221,7 +230,7 @@ encode_thumb_immediate(unsigned int v)
|
||||||
return ((v & 0xff) | (1 << 12));
|
return ((v & 0xff) | (1 << 12));
|
||||||
/* abcdefgh 00000000 abcdefgh 00000000 */
|
/* abcdefgh 00000000 abcdefgh 00000000 */
|
||||||
if (((v & 0xffff0000) >> 16) == (v & 0xffff) && (v & 0xff) == 0)
|
if (((v & 0xffff0000) >> 16) == (v & 0xffff) && (v & 0xff) == 0)
|
||||||
return ((v & 0x000000ff) | (2 << 12));
|
return (((v & 0x0000ff00) >> 8) | (2 << 12));
|
||||||
/* abcdefgh abcdefgh abcdefgh abcdefgh */
|
/* abcdefgh abcdefgh abcdefgh abcdefgh */
|
||||||
if ( (v & 0xff) == ((v & 0xff00) >> 8) &&
|
if ( (v & 0xff) == ((v & 0xff00) >> 8) &&
|
||||||
((v & 0xff00) >> 8) == ((v & 0xff0000) >> 16) &&
|
((v & 0xff00) >> 8) == ((v & 0xff0000) >> 16) &&
|
||||||
|
|
@ -265,9 +274,12 @@ write_wide_thumb(uint32_t *loc, uint32_t v)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
offset_in_jmp_range(int32_t offset)
|
offset_in_jmp_range(int32_t offset, int flags)
|
||||||
{
|
{
|
||||||
return -0x800000 <= offset && offset <= 0x7fffff;
|
if (!(offset & 1) && flags | JIT_RELOC_B)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -0x1000000 <= offset && offset <= 0xffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t
|
static int32_t
|
||||||
|
|
@ -287,7 +299,7 @@ decode_thumb_jump(uint32_t v)
|
||||||
ret |= i2 << 21;
|
ret |= i2 << 21;
|
||||||
ret |= hi << 11;
|
ret |= hi << 11;
|
||||||
ret |= lo;
|
ret |= lo;
|
||||||
return ret;
|
return ret << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint32_t thumb_jump_mask = 0xf800d000;
|
static const uint32_t thumb_jump_mask = 0xf800d000;
|
||||||
|
|
@ -295,14 +307,15 @@ static const uint32_t thumb_jump_mask = 0xf800d000;
|
||||||
static uint32_t
|
static uint32_t
|
||||||
encode_thumb_jump(int32_t v)
|
encode_thumb_jump(int32_t v)
|
||||||
{
|
{
|
||||||
ASSERT(offset_in_jmp_range(v));
|
ASSERT(offset_in_jmp_range(v, 0));
|
||||||
|
v >>= 1;
|
||||||
uint32_t s = !!(v & 0x800000);
|
uint32_t s = !!(v & 0x800000);
|
||||||
uint32_t i1 = !!(v & 0x400000);
|
uint32_t i1 = !!(v & 0x400000);
|
||||||
uint32_t i2 = !!(v & 0x200000);
|
uint32_t i2 = !!(v & 0x200000);
|
||||||
uint32_t j1 = s ? i1 : !i1;
|
uint32_t j1 = s ? i1 : !i1;
|
||||||
uint32_t j2 = s ? i2 : !i2;
|
uint32_t j2 = s ? i2 : !i2;
|
||||||
uint32_t ret = (s<<26)|((v&0x1ff800)<<5)|(j1<<13)|(j2<<11)|(v&0x7ff);
|
uint32_t ret = (s<<26)|((v&0x1ff800)<<5)|(j1<<13)|(j2<<11)|(v&0x7ff);
|
||||||
ASSERT(decode_thumb_jump(ret) == v);
|
ASSERT(decode_thumb_jump(ret) == v << 1);
|
||||||
ASSERT((ret & thumb_jump_mask) == 0);
|
ASSERT((ret & thumb_jump_mask) == 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -310,7 +323,13 @@ encode_thumb_jump(int32_t v)
|
||||||
static uint32_t
|
static uint32_t
|
||||||
patch_thumb_jump(uint32_t inst, int32_t v)
|
patch_thumb_jump(uint32_t inst, int32_t v)
|
||||||
{
|
{
|
||||||
return (inst & thumb_jump_mask) | encode_thumb_jump(v);
|
inst &= thumb_jump_mask;
|
||||||
|
if (!(v & 1)) {
|
||||||
|
ASSERT(inst == THUMB2_BLI || inst == THUMB2_BLXI);
|
||||||
|
v = (v + 2) & ~2;
|
||||||
|
inst = THUMB2_BLXI;
|
||||||
|
}
|
||||||
|
return inst | encode_thumb_jump(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t
|
static int32_t
|
||||||
|
|
@ -325,15 +344,23 @@ patch_jmp_offset(uint32_t *loc, int32_t v)
|
||||||
write_wide_thumb(loc, patch_thumb_jump(read_wide_thumb(loc), v));
|
write_wide_thumb(loc, patch_thumb_jump(read_wide_thumb(loc), v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
patch_veneer_jmp_offset(uint32_t *loc, int32_t v)
|
||||||
|
{
|
||||||
|
ASSERT(!(v & 1));
|
||||||
|
patch_jmp_offset(loc, v | 1);
|
||||||
|
}
|
||||||
|
|
||||||
static jit_reloc_t
|
static jit_reloc_t
|
||||||
emit_thumb_jump(jit_state_t *_jit, uint32_t inst)
|
emit_thumb_jump(jit_state_t *_jit, uint32_t inst)
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
uint8_t *pc_base = _jit->pc.uc + 4;
|
uint8_t *pc_base = _jit->pc.uc + 4;
|
||||||
uint8_t rsh = 1;
|
int32_t off = (uint8_t*)jit_address(_jit) - pc_base;
|
||||||
int32_t off = (_jit->pc.uc - pc_base) >> rsh;
|
enum jit_reloc_kind kind = JIT_RELOC_JMP_WITH_VENEER;
|
||||||
jit_reloc_t ret =
|
if (inst == THUMB2_B)
|
||||||
jit_reloc (_jit, JIT_RELOC_JMP_WITH_VENEER, 0, _jit->pc.uc, pc_base, rsh);
|
kind |= JIT_RELOC_B;
|
||||||
|
jit_reloc_t ret = jit_reloc (_jit, kind, 0, _jit->pc.uc, pc_base, 0);
|
||||||
uint8_t thumb_jump_width = 24;
|
uint8_t thumb_jump_width = 24;
|
||||||
if (add_pending_literal(_jit, ret, thumb_jump_width - 1)) {
|
if (add_pending_literal(_jit, ret, thumb_jump_width - 1)) {
|
||||||
emit_wide_thumb(_jit, patch_thumb_jump(inst, off));
|
emit_wide_thumb(_jit, patch_thumb_jump(inst, off));
|
||||||
|
|
@ -343,9 +370,12 @@ emit_thumb_jump(jit_state_t *_jit, uint32_t inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
offset_in_jcc_range(int32_t v)
|
offset_in_jcc_range(int32_t v, int flags)
|
||||||
{
|
{
|
||||||
return -0x80000 <= v && v <= 0x7ffff;
|
if (!(v & 1))
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -0x100000 <= v && v <= 0xfffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t
|
static int32_t
|
||||||
|
|
@ -363,7 +393,7 @@ decode_thumb_cc_jump(uint32_t v)
|
||||||
ret |= j1 << 17;
|
ret |= j1 << 17;
|
||||||
ret |= hi << 11;
|
ret |= hi << 11;
|
||||||
ret |= lo;
|
ret |= lo;
|
||||||
return ret;
|
return ret << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint32_t thumb_cc_jump_mask = 0xfbc0d000;
|
static const uint32_t thumb_cc_jump_mask = 0xfbc0d000;
|
||||||
|
|
@ -371,14 +401,15 @@ static const uint32_t thumb_cc_jump_mask = 0xfbc0d000;
|
||||||
static uint32_t
|
static uint32_t
|
||||||
encode_thumb_cc_jump(int32_t v)
|
encode_thumb_cc_jump(int32_t v)
|
||||||
{
|
{
|
||||||
ASSERT(offset_in_jcc_range(v));
|
ASSERT(offset_in_jcc_range(v, 0));
|
||||||
|
v >>= 1;
|
||||||
uint32_t s = !!(v & 0x80000);
|
uint32_t s = !!(v & 0x80000);
|
||||||
uint32_t j2 = !!(v & 0x40000);
|
uint32_t j2 = !!(v & 0x40000);
|
||||||
uint32_t j1 = !!(v & 0x20000);
|
uint32_t j1 = !!(v & 0x20000);
|
||||||
uint32_t hi = (v >> 11) & 0x3f;
|
uint32_t hi = (v >> 11) & 0x3f;
|
||||||
uint32_t lo = v & 0x7ff;
|
uint32_t lo = v & 0x7ff;
|
||||||
uint32_t ret = (s<<26)|(hi << 16)|(j1<<13)|(j2<<11)|lo;
|
uint32_t ret = (s<<26)|(hi << 16)|(j1<<13)|(j2<<11)|lo;
|
||||||
ASSERT(decode_thumb_cc_jump(ret) == v);
|
ASSERT(decode_thumb_cc_jump(ret) == v << 1);
|
||||||
ASSERT((ret & thumb_cc_jump_mask) == 0);
|
ASSERT((ret & thumb_cc_jump_mask) == 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -401,15 +432,21 @@ patch_jcc_offset(uint32_t *loc, int32_t v)
|
||||||
write_wide_thumb(loc, patch_thumb_cc_jump(read_wide_thumb(loc), v));
|
write_wide_thumb(loc, patch_thumb_cc_jump(read_wide_thumb(loc), v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
patch_veneer_jcc_offset(uint32_t *loc, int32_t v)
|
||||||
|
{
|
||||||
|
ASSERT(!(v & 1));
|
||||||
|
patch_jcc_offset(loc, v | 1);
|
||||||
|
}
|
||||||
|
|
||||||
static jit_reloc_t
|
static jit_reloc_t
|
||||||
emit_thumb_cc_jump(jit_state_t *_jit, uint32_t inst)
|
emit_thumb_cc_jump(jit_state_t *_jit, uint32_t inst)
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
uint8_t *pc_base = _jit->pc.uc + 4;
|
uint8_t *pc_base = _jit->pc.uc + 4;
|
||||||
uint8_t rsh = 1;
|
int32_t off = (uint8_t*)jit_address(_jit) - pc_base;
|
||||||
int32_t off = (_jit->pc.uc - pc_base) >> rsh;
|
|
||||||
jit_reloc_t ret =
|
jit_reloc_t ret =
|
||||||
jit_reloc (_jit, JIT_RELOC_JCC_WITH_VENEER, 0, _jit->pc.uc, pc_base, rsh);
|
jit_reloc (_jit, JIT_RELOC_JCC_WITH_VENEER, 0, _jit->pc.uc, pc_base, 0);
|
||||||
uint8_t thumb_cc_jump_width = 20;
|
uint8_t thumb_cc_jump_width = 20;
|
||||||
if (add_pending_literal(_jit, ret, thumb_cc_jump_width - 1)) {
|
if (add_pending_literal(_jit, ret, thumb_cc_jump_width - 1)) {
|
||||||
emit_wide_thumb(_jit, patch_thumb_cc_jump(inst, off));
|
emit_wide_thumb(_jit, patch_thumb_cc_jump(inst, off));
|
||||||
|
|
@ -1028,12 +1065,6 @@ T2_BLI(jit_state_t *_jit)
|
||||||
return tb(_jit, THUMB2_BLI);
|
return tb(_jit, THUMB2_BLI);
|
||||||
}
|
}
|
||||||
|
|
||||||
static jit_reloc_t
|
|
||||||
T2_BLXI(jit_state_t *_jit)
|
|
||||||
{
|
|
||||||
return tb(_jit, THUMB2_BLXI);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum dmb_option { DMB_ISH = 0xb };
|
enum dmb_option { DMB_ISH = 0xb };
|
||||||
static void
|
static void
|
||||||
T1_DMB(jit_state_t *_jit, enum dmb_option option)
|
T1_DMB(jit_state_t *_jit, enum dmb_option option)
|
||||||
|
|
@ -2052,7 +2083,7 @@ rshi_u(jit_state_t *_jit, int32_t r0, int32_t r1, jit_word_t i0)
|
||||||
static void
|
static void
|
||||||
jmpr(jit_state_t *_jit, int32_t r0)
|
jmpr(jit_state_t *_jit, int32_t r0)
|
||||||
{
|
{
|
||||||
T1_MOV(_jit, jit_gpr_regno(_PC), r0);
|
T1_BX(_jit, r0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static jit_reloc_t
|
static jit_reloc_t
|
||||||
|
|
@ -2064,8 +2095,6 @@ jmp(jit_state_t *_jit)
|
||||||
static void
|
static void
|
||||||
jmpi(jit_state_t *_jit, jit_word_t i0)
|
jmpi(jit_state_t *_jit, jit_word_t i0)
|
||||||
{
|
{
|
||||||
/* Strip thumb bit, if any. */
|
|
||||||
i0 &= ~1;
|
|
||||||
return jit_patch_there(_jit, jmp(_jit), (void*)i0);
|
return jit_patch_there(_jit, jmp(_jit), (void*)i0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2905,10 +2934,7 @@ callr(jit_state_t *_jit, int32_t r0)
|
||||||
static void
|
static void
|
||||||
calli(jit_state_t *_jit, jit_word_t i0)
|
calli(jit_state_t *_jit, jit_word_t i0)
|
||||||
{
|
{
|
||||||
if (i0 & 1)
|
jit_patch_there(_jit, T2_BLI(_jit), (void*)i0);
|
||||||
jit_patch_there(_jit, T2_BLI(_jit), (void*)(i0 & ~1));
|
|
||||||
else
|
|
||||||
jit_patch_there(_jit, T2_BLXI(_jit), (void*)i0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -2990,8 +3016,7 @@ static void
|
||||||
patch_jmp_without_veneer(jit_state_t *_jit, uint32_t *loc)
|
patch_jmp_without_veneer(jit_state_t *_jit, uint32_t *loc)
|
||||||
{
|
{
|
||||||
uint8_t *pc_base = ((uint8_t *)loc) + 4;
|
uint8_t *pc_base = ((uint8_t *)loc) + 4;
|
||||||
uint8_t rsh = 1;
|
int32_t off = (uint8_t*)jit_address(_jit) - pc_base;
|
||||||
int32_t off = (_jit->pc.uc - pc_base) >> rsh;
|
|
||||||
write_wide_thumb(loc, THUMB2_B | encode_thumb_jump(off));
|
write_wide_thumb(loc, THUMB2_B | encode_thumb_jump(off));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3014,11 +3039,10 @@ emit_veneer(jit_state_t *_jit, jit_pointer_t target)
|
||||||
{
|
{
|
||||||
uint16_t thumb1_ldr = 0x4800;
|
uint16_t thumb1_ldr = 0x4800;
|
||||||
int32_t tmp = jit_gpr_regno(JIT_TMP1);
|
int32_t tmp = jit_gpr_regno(JIT_TMP1);
|
||||||
int32_t rd = jit_gpr_regno(_PC);
|
|
||||||
ASSERT(tmp < 8);
|
ASSERT(tmp < 8);
|
||||||
// Loaded addr is 4 bytes after the LDR, which is aligned, so offset is 0.
|
// Loaded addr is 4 bytes after the LDR, which is aligned, so offset is 0.
|
||||||
emit_u16(_jit, thumb1_ldr | (tmp << 8));
|
emit_u16(_jit, thumb1_ldr | (tmp << 8));
|
||||||
emit_u16(_jit, THUMB_MOV|((_u4(rd)&8)<<4)|(_u4(tmp)<<3)|(rd&7));
|
emit_u16(_jit, THUMB_BX|(_u4(tmp)<<3));
|
||||||
emit_u32(_jit, (uint32_t) target);
|
emit_u32(_jit, (uint32_t) target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
|
* Copyright (C) 2012-2020 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GNU lightning.
|
* This file is part of GNU lightning.
|
||||||
*
|
*
|
||||||
|
|
@ -105,11 +105,13 @@ enum guard_pool { GUARD_NEEDED, NO_GUARD_NEEDED };
|
||||||
static void emit_literal_pool(jit_state_t *_jit, enum guard_pool guard);
|
static void emit_literal_pool(jit_state_t *_jit, enum guard_pool guard);
|
||||||
|
|
||||||
static int32_t read_jmp_offset(uint32_t *loc);
|
static int32_t read_jmp_offset(uint32_t *loc);
|
||||||
static int offset_in_jmp_range(ptrdiff_t offset);
|
static int offset_in_jmp_range(ptrdiff_t offset, int flags);
|
||||||
static void patch_jmp_offset(uint32_t *loc, ptrdiff_t offset);
|
static void patch_jmp_offset(uint32_t *loc, ptrdiff_t offset);
|
||||||
|
static void patch_veneer_jmp_offset(uint32_t *loc, ptrdiff_t offset);
|
||||||
static int32_t read_jcc_offset(uint32_t *loc);
|
static int32_t read_jcc_offset(uint32_t *loc);
|
||||||
static int offset_in_jcc_range(ptrdiff_t offset);
|
static int offset_in_jcc_range(ptrdiff_t offset, int flags);
|
||||||
static void patch_jcc_offset(uint32_t *loc, ptrdiff_t offset);
|
static void patch_jcc_offset(uint32_t *loc, ptrdiff_t offset);
|
||||||
|
static void patch_veneer_jcc_offset(uint32_t *loc, ptrdiff_t offset);
|
||||||
static void patch_veneer(uint32_t *loc, jit_pointer_t addr);
|
static void patch_veneer(uint32_t *loc, jit_pointer_t addr);
|
||||||
static int32_t read_load_from_pool_offset(uint32_t *loc);
|
static int32_t read_load_from_pool_offset(uint32_t *loc);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -169,7 +171,7 @@ jit_pointer_t
|
||||||
jit_address(jit_state_t *_jit)
|
jit_address(jit_state_t *_jit)
|
||||||
{
|
{
|
||||||
ASSERT (_jit->start);
|
ASSERT (_jit->start);
|
||||||
return _jit->pc.uc;
|
return jit_address_to_function_pointer (_jit->pc.uc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -378,8 +380,11 @@ jit_patch_there(jit_state_t* _jit, jit_reloc_t reloc, jit_pointer_t addr)
|
||||||
ptrdiff_t diff = (uint8_t*)addr - pc_base;
|
ptrdiff_t diff = (uint8_t*)addr - pc_base;
|
||||||
ASSERT((diff & ((1 << reloc.rsh) - 1)) == 0);
|
ASSERT((diff & ((1 << reloc.rsh) - 1)) == 0);
|
||||||
diff >>= reloc.rsh;
|
diff >>= reloc.rsh;
|
||||||
|
#ifdef JIT_NEEDS_LITERAL_POOL
|
||||||
|
int flags = reloc.kind & ~JIT_RELOC_MASK;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (reloc.kind)
|
switch (reloc.kind & JIT_RELOC_MASK)
|
||||||
{
|
{
|
||||||
case JIT_RELOC_ABSOLUTE:
|
case JIT_RELOC_ABSOLUTE:
|
||||||
if (sizeof(diff) == 4)
|
if (sizeof(diff) == 4)
|
||||||
|
|
@ -404,7 +409,7 @@ jit_patch_there(jit_state_t* _jit, jit_reloc_t reloc, jit_pointer_t addr)
|
||||||
uint8_t *target = pc_base + (voff << reloc.rsh);
|
uint8_t *target = pc_base + (voff << reloc.rsh);
|
||||||
if (target == loc.uc) {
|
if (target == loc.uc) {
|
||||||
// PC still in range to reify direct branch.
|
// PC still in range to reify direct branch.
|
||||||
if (offset_in_jmp_range(diff)) {
|
if (offset_in_jmp_range(diff, flags)) {
|
||||||
// Target also in range: reify direct branch.
|
// Target also in range: reify direct branch.
|
||||||
patch_jmp_offset(loc.ui, diff);
|
patch_jmp_offset(loc.ui, diff);
|
||||||
remove_pending_literal(_jit, reloc);
|
remove_pending_literal(_jit, reloc);
|
||||||
|
|
@ -423,7 +428,7 @@ jit_patch_there(jit_state_t* _jit, jit_reloc_t reloc, jit_pointer_t addr)
|
||||||
int32_t voff = read_jcc_offset(loc.ui);
|
int32_t voff = read_jcc_offset(loc.ui);
|
||||||
uint8_t *target = pc_base + (voff << reloc.rsh);
|
uint8_t *target = pc_base + (voff << reloc.rsh);
|
||||||
if (target == loc.uc) {
|
if (target == loc.uc) {
|
||||||
if (offset_in_jcc_range(diff)) {
|
if (offset_in_jcc_range(diff, flags)) {
|
||||||
patch_jcc_offset(loc.ui, diff);
|
patch_jcc_offset(loc.ui, diff);
|
||||||
remove_pending_literal(_jit, reloc);
|
remove_pending_literal(_jit, reloc);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1238,8 +1243,8 @@ static void
|
||||||
reset_literal_pool(jit_state_t *_jit, struct jit_literal_pool *pool)
|
reset_literal_pool(jit_state_t *_jit, struct jit_literal_pool *pool)
|
||||||
{
|
{
|
||||||
pool->deadline = _jit->limit - _jit->start;
|
pool->deadline = _jit->limit - _jit->start;
|
||||||
pool->size = 0;
|
|
||||||
memset(pool->entries, 0, sizeof(pool->entries[0]) * pool->size);
|
memset(pool->entries, 0, sizeof(pool->entries[0]) * pool->size);
|
||||||
|
pool->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INITIAL_LITERAL_POOL_CAPACITY 12
|
#define INITIAL_LITERAL_POOL_CAPACITY 12
|
||||||
|
|
@ -1365,13 +1370,13 @@ emit_literal_pool(jit_state_t *_jit, enum guard_pool guard)
|
||||||
if (_jit->overflow)
|
if (_jit->overflow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (entry->reloc.kind) {
|
switch (entry->reloc.kind & JIT_RELOC_MASK) {
|
||||||
case JIT_RELOC_JMP_WITH_VENEER:
|
case JIT_RELOC_JMP_WITH_VENEER:
|
||||||
patch_jmp_offset((uint32_t*) loc, diff);
|
patch_veneer_jmp_offset((uint32_t*) loc, diff);
|
||||||
emit_veneer(_jit, (void*) (uintptr_t) entry->value);
|
emit_veneer(_jit, (void*) (uintptr_t) entry->value);
|
||||||
break;
|
break;
|
||||||
case JIT_RELOC_JCC_WITH_VENEER:
|
case JIT_RELOC_JCC_WITH_VENEER:
|
||||||
patch_jcc_offset((uint32_t*) loc, diff);
|
patch_veneer_jcc_offset((uint32_t*) loc, diff);
|
||||||
emit_veneer(_jit, (void*) (uintptr_t) entry->value);
|
emit_veneer(_jit, (void*) (uintptr_t) entry->value);
|
||||||
break;
|
break;
|
||||||
case JIT_RELOC_LOAD_FROM_POOL:
|
case JIT_RELOC_LOAD_FROM_POOL:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
TESTS=$(sort $(basename $(wildcard *.c)))
|
TESTS=$(sort $(basename $(wildcard *.c)))
|
||||||
TARGETS=native ia32 aarch64 armv7
|
TARGETS ?= native ia32 aarch64 armv7
|
||||||
|
|
||||||
# Suitable values of cross-compiler variables for Debian:
|
# Suitable values of cross-compiler variables for Debian:
|
||||||
#
|
#
|
||||||
|
|
@ -17,9 +17,9 @@ TARGETS=native ia32 aarch64 armv7
|
||||||
# gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6:arm64
|
# gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6:arm64
|
||||||
#
|
#
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CC_IA32=guix environment --pure -s i686-linux --ad-hoc gcc-toolchain glibc -- gcc
|
CC_IA32=guix environment --pure -s i686-linux --ad-hoc gcc-toolchain -- gcc
|
||||||
CC_AARCH64=guix environment --pure -s aarch64-linux --ad-hoc gcc-toolchain glibc -- gcc
|
CC_AARCH64=guix environment --pure -s aarch64-linux --ad-hoc gcc-toolchain -- gcc
|
||||||
CC_ARMv7=guix environment --pure -s armhf-linux --ad-hoc gcc-toolchain glibc -- gcc
|
CC_ARMv7=guix environment --pure -s armhf-linux --ad-hoc gcc-toolchain -- gcc
|
||||||
CFLAGS = -Wall -O0 -g
|
CFLAGS = -Wall -O0 -g
|
||||||
|
|
||||||
all: $(foreach TARGET,$(TARGETS),$(addprefix test-$(TARGET)-,$(TESTS)))
|
all: $(foreach TARGET,$(TARGETS),$(addprefix test-$(TARGET)-,$(TESTS)))
|
||||||
|
|
|
||||||
25
libguile/lightening/tests/jmpi_local.c
Normal file
25
libguile/lightening/tests/jmpi_local.c
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
|
||||||
|
{
|
||||||
|
jit_begin(j, arena_base, arena_size);
|
||||||
|
|
||||||
|
jit_reloc_t r = jit_jmp (j);
|
||||||
|
jit_reti (j, 0);
|
||||||
|
jit_pointer_t addr = jit_address (j);
|
||||||
|
jit_reti (j, 1);
|
||||||
|
jit_patch_here (j, r);
|
||||||
|
jit_jmpi (j, addr);
|
||||||
|
jit_reti (j, 2);
|
||||||
|
|
||||||
|
int (*f)(void) = jit_end(j, NULL);
|
||||||
|
|
||||||
|
ASSERT(f() == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
return main_helper(argc, argv, run_test);
|
||||||
|
}
|
||||||
22
libguile/lightening/tests/movi.c
Normal file
22
libguile/lightening/tests/movi.c
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
run_test(jit_state_t *j, uint8_t *arena_base, size_t arena_size)
|
||||||
|
{
|
||||||
|
jit_begin(j, arena_base, arena_size);
|
||||||
|
size_t align = jit_enter_jit_abi(j, 0, 0, 0);
|
||||||
|
|
||||||
|
jit_movi(j, JIT_R0, 0xa500a500);
|
||||||
|
jit_leave_jit_abi(j, 0, 0, align);
|
||||||
|
jit_retr(j, JIT_R0);
|
||||||
|
|
||||||
|
jit_uword_t (*f)(void) = jit_end(j, NULL);
|
||||||
|
|
||||||
|
ASSERT(f() == 0xa500a500);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
return main_helper(argc, argv, run_test);
|
||||||
|
}
|
||||||
|
|
@ -704,7 +704,7 @@ scm_read_string_like_syntax (int chr, SCM port, scm_t_read_opts *opts)
|
||||||
break;
|
break;
|
||||||
bad_escaped:
|
bad_escaped:
|
||||||
scm_i_input_error (FUNC_NAME, port,
|
scm_i_input_error (FUNC_NAME, port,
|
||||||
"illegal character in escape sequence: ~S",
|
"invalid character in escape sequence: ~S",
|
||||||
scm_list_1 (SCM_MAKE_CHAR (c)));
|
scm_list_1 (SCM_MAKE_CHAR (c)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* srfi-1.c --- SRFI-1 procedures for Guile
|
/* srfi-1.c --- SRFI-1 procedures for Guile
|
||||||
|
|
||||||
Copyright 1995-1997,2000-2003,2005-2006,2008-2011,2013-2014,2018
|
Copyright 1995-1997,2000-2003,2005-2006,2008-2011,2013-2014,2018,2020
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of Guile.
|
This file is part of Guile.
|
||||||
|
|
@ -575,47 +575,6 @@ SCM_DEFINE (scm_srfi1_delete_duplicates_x, "delete-duplicates!", 1, 1, 0,
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
||||||
SCM_DEFINE (scm_srfi1_find, "find", 2, 0, 0,
|
|
||||||
(SCM pred, SCM lst),
|
|
||||||
"Return the first element of @var{lst} which satisfies the\n"
|
|
||||||
"predicate @var{pred}, or return @code{#f} if no such element is\n"
|
|
||||||
"found.")
|
|
||||||
#define FUNC_NAME s_scm_srfi1_find
|
|
||||||
{
|
|
||||||
SCM_VALIDATE_PROC (SCM_ARG1, pred);
|
|
||||||
|
|
||||||
for ( ; scm_is_pair (lst); lst = SCM_CDR (lst))
|
|
||||||
{
|
|
||||||
SCM elem = SCM_CAR (lst);
|
|
||||||
if (scm_is_true (scm_call_1 (pred, elem)))
|
|
||||||
return elem;
|
|
||||||
}
|
|
||||||
SCM_ASSERT_TYPE (SCM_NULL_OR_NIL_P (lst), lst, SCM_ARG2, FUNC_NAME, "list");
|
|
||||||
|
|
||||||
return SCM_BOOL_F;
|
|
||||||
}
|
|
||||||
#undef FUNC_NAME
|
|
||||||
|
|
||||||
|
|
||||||
SCM_DEFINE (scm_srfi1_find_tail, "find-tail", 2, 0, 0,
|
|
||||||
(SCM pred, SCM lst),
|
|
||||||
"Return the first pair of @var{lst} whose @sc{car} satisfies the\n"
|
|
||||||
"predicate @var{pred}, or return @code{#f} if no such element is\n"
|
|
||||||
"found.")
|
|
||||||
#define FUNC_NAME s_scm_srfi1_find_tail
|
|
||||||
{
|
|
||||||
SCM_VALIDATE_PROC (SCM_ARG1, pred);
|
|
||||||
|
|
||||||
for ( ; scm_is_pair (lst); lst = SCM_CDR (lst))
|
|
||||||
if (scm_is_true (scm_call_1 (pred, SCM_CAR (lst))))
|
|
||||||
return lst;
|
|
||||||
SCM_ASSERT_TYPE (SCM_NULL_OR_NIL_P (lst), lst, SCM_ARG2, FUNC_NAME, "list");
|
|
||||||
|
|
||||||
return SCM_BOOL_F;
|
|
||||||
}
|
|
||||||
#undef FUNC_NAME
|
|
||||||
|
|
||||||
SCM_DEFINE (scm_srfi1_length_plus, "length+", 1, 0, 0,
|
SCM_DEFINE (scm_srfi1_length_plus, "length+", 1, 0, 0,
|
||||||
(SCM lst),
|
(SCM lst),
|
||||||
"Return the length of @var{lst}, or @code{#f} if @var{lst} is\n"
|
"Return the length of @var{lst}, or @code{#f} if @var{lst} is\n"
|
||||||
|
|
@ -751,37 +710,6 @@ SCM_DEFINE (scm_srfi1_lset_difference_x, "lset-difference!", 2, 0, 1,
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
||||||
SCM_DEFINE (scm_srfi1_assoc, "assoc", 2, 1, 0,
|
|
||||||
(SCM key, SCM alist, SCM pred),
|
|
||||||
"Behaves like @code{assq} but uses third argument @var{pred}\n"
|
|
||||||
"for key comparison. If @var{pred} is not supplied,\n"
|
|
||||||
"@code{equal?} is used. (Extended from R5RS.)\n")
|
|
||||||
#define FUNC_NAME s_scm_srfi1_assoc
|
|
||||||
{
|
|
||||||
SCM ls = alist;
|
|
||||||
scm_t_trampoline_2 equal_p;
|
|
||||||
if (SCM_UNBNDP (pred))
|
|
||||||
equal_p = equal_trampoline;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SCM_VALIDATE_PROC (SCM_ARG3, pred);
|
|
||||||
equal_p = scm_call_2;
|
|
||||||
}
|
|
||||||
for(; scm_is_pair (ls); ls = SCM_CDR (ls))
|
|
||||||
{
|
|
||||||
SCM tmp = SCM_CAR (ls);
|
|
||||||
SCM_ASSERT_TYPE (scm_is_pair (tmp), alist, SCM_ARG2, FUNC_NAME,
|
|
||||||
"association list");
|
|
||||||
if (scm_is_true (equal_p (pred, key, SCM_CAR (tmp))))
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
SCM_ASSERT_TYPE (SCM_NULL_OR_NIL_P (ls), alist, SCM_ARG2, FUNC_NAME,
|
|
||||||
"association list");
|
|
||||||
return SCM_BOOL_F;
|
|
||||||
}
|
|
||||||
#undef FUNC_NAME
|
|
||||||
|
|
||||||
SCM_DEFINE (scm_srfi1_partition, "partition", 2, 0, 0,
|
SCM_DEFINE (scm_srfi1_partition, "partition", 2, 0, 0,
|
||||||
(SCM pred, SCM list),
|
(SCM pred, SCM list),
|
||||||
"Partition the elements of @var{list} with predicate @var{pred}.\n"
|
"Partition the elements of @var{list} with predicate @var{pred}.\n"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/* srfi-1.h --- SRFI-1 procedures for Guile
|
/* srfi-1.h --- SRFI-1 procedures for Guile
|
||||||
Copyright 2002-2003,2005-2006,2010-2011,2018
|
Copyright 2002-2003,2005-2006,2010-2011,2018,2020
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of Guile.
|
This file is part of Guile.
|
||||||
|
|
@ -33,12 +33,9 @@ SCM_INTERNAL SCM scm_srfi1_delete (SCM x, SCM lst, SCM pred);
|
||||||
SCM_INTERNAL SCM scm_srfi1_delete_x (SCM x, SCM lst, SCM pred);
|
SCM_INTERNAL SCM scm_srfi1_delete_x (SCM x, SCM lst, SCM pred);
|
||||||
SCM_INTERNAL SCM scm_srfi1_delete_duplicates (SCM lst, SCM pred);
|
SCM_INTERNAL SCM scm_srfi1_delete_duplicates (SCM lst, SCM pred);
|
||||||
SCM_INTERNAL SCM scm_srfi1_delete_duplicates_x (SCM lst, SCM pred);
|
SCM_INTERNAL SCM scm_srfi1_delete_duplicates_x (SCM lst, SCM pred);
|
||||||
SCM_INTERNAL SCM scm_srfi1_find (SCM pred, SCM lst);
|
|
||||||
SCM_INTERNAL SCM scm_srfi1_find_tail (SCM pred, SCM lst);
|
|
||||||
SCM_INTERNAL SCM scm_srfi1_length_plus (SCM lst);
|
SCM_INTERNAL SCM scm_srfi1_length_plus (SCM lst);
|
||||||
SCM_INTERNAL SCM scm_srfi1_lset_difference_x (SCM equal, SCM lst, SCM rest);
|
SCM_INTERNAL SCM scm_srfi1_lset_difference_x (SCM equal, SCM lst, SCM rest);
|
||||||
SCM_INTERNAL SCM scm_srfi1_list_copy (SCM lst);
|
SCM_INTERNAL SCM scm_srfi1_list_copy (SCM lst);
|
||||||
SCM_INTERNAL SCM scm_srfi1_assoc (SCM key, SCM alist, SCM pred);
|
|
||||||
SCM_INTERNAL SCM scm_srfi1_partition (SCM pred, SCM list);
|
SCM_INTERNAL SCM scm_srfi1_partition (SCM pred, SCM list);
|
||||||
SCM_INTERNAL SCM scm_srfi1_partition_x (SCM pred, SCM list);
|
SCM_INTERNAL SCM scm_srfi1_partition_x (SCM pred, SCM list);
|
||||||
SCM_INTERNAL SCM scm_srfi1_remove (SCM pred, SCM list);
|
SCM_INTERNAL SCM scm_srfi1_remove (SCM pred, SCM list);
|
||||||
|
|
|
||||||
|
|
@ -382,11 +382,12 @@ SCM_SYMBOL (scm_sym_prefix, "prefix");
|
||||||
|
|
||||||
SCM_DEFINE (scm_string_join, "string-join", 1, 2, 0,
|
SCM_DEFINE (scm_string_join, "string-join", 1, 2, 0,
|
||||||
(SCM ls, SCM delimiter, SCM grammar),
|
(SCM ls, SCM delimiter, SCM grammar),
|
||||||
"Append the string in the string list @var{ls}, using the string\n"
|
"Append the string in the string list @var{ls}, using the string\n"
|
||||||
"@var{delimiter} as a delimiter between the elements of @var{ls}.\n"
|
"@var{delimiter} as a delimiter between the elements of @var{ls}.\n"
|
||||||
"@var{grammar} is a symbol which specifies how the delimiter is\n"
|
"@var{delimiter} defaults to @w{@samp{ }}, that is, strings in @var{ls}\n"
|
||||||
"placed between the strings, and defaults to the symbol\n"
|
"are appended with the space character in between them. @var{grammar} is\n"
|
||||||
"@code{infix}.\n"
|
"a symbol which specifies how the delimiter is placed between the\n"
|
||||||
|
"strings, and defaults to the symbol @code{infix}.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"@table @code\n"
|
"@table @code\n"
|
||||||
"@item infix\n"
|
"@item infix\n"
|
||||||
|
|
|
||||||
|
|
@ -99,13 +99,28 @@ process (based on pipes) is created and returned. @var{mode} specifies
|
||||||
whether an input, an output or an input-output port to the process is
|
whether an input, an output or an input-output port to the process is
|
||||||
created: it should be the value of @code{OPEN_READ}, @code{OPEN_WRITE}
|
created: it should be the value of @code{OPEN_READ}, @code{OPEN_WRITE}
|
||||||
or @code{OPEN_BOTH}."
|
or @code{OPEN_BOTH}."
|
||||||
|
(define (unbuffered port)
|
||||||
|
(setvbuf port 'none)
|
||||||
|
port)
|
||||||
|
|
||||||
|
(define (fdes-pair ports)
|
||||||
|
(and ports
|
||||||
|
(cons (port->fdes (car ports)) (port->fdes (cdr ports)))))
|
||||||
|
|
||||||
(let* ((from (and (or (string=? mode OPEN_READ)
|
(let* ((from (and (or (string=? mode OPEN_READ)
|
||||||
(string=? mode OPEN_BOTH)) (pipe->fdes)))
|
(string=? mode OPEN_BOTH))
|
||||||
|
(pipe)))
|
||||||
(to (and (or (string=? mode OPEN_WRITE)
|
(to (and (or (string=? mode OPEN_WRITE)
|
||||||
(string=? mode OPEN_BOTH)) (pipe->fdes)))
|
(string=? mode OPEN_BOTH))
|
||||||
(pid (piped-process command args from to)))
|
(pipe)))
|
||||||
(values (and from (fdes->inport (car from)))
|
(pid (piped-process command args
|
||||||
(and to (fdes->outport (cdr to))) pid)))
|
(fdes-pair from)
|
||||||
|
(fdes-pair to))))
|
||||||
|
;; The original 'open-process' procedure would return unbuffered
|
||||||
|
;; ports; do the same here.
|
||||||
|
(values (and from (unbuffered (car from)))
|
||||||
|
(and to (unbuffered (cdr to)))
|
||||||
|
pid)))
|
||||||
|
|
||||||
(define (open-pipe* mode command . args)
|
(define (open-pipe* mode command . args)
|
||||||
"Executes the program @var{command} with optional arguments
|
"Executes the program @var{command} with optional arguments
|
||||||
|
|
@ -200,10 +215,10 @@ information on how to interpret this value."
|
||||||
(open-pipe command OPEN_BOTH))
|
(open-pipe command OPEN_BOTH))
|
||||||
|
|
||||||
(define (pipeline commands)
|
(define (pipeline commands)
|
||||||
"Execute a pipeline of @var(commands) -- where each command is a list of a
|
"Execute a pipeline of @var{commands}, where each command is a list of a
|
||||||
program and its arguments as strings -- returning an input port to the
|
program and its arguments as strings, returning an input port to the
|
||||||
end of the pipeline, an output port to the beginning of the pipeline and
|
end of the pipeline, an output port to the beginning of the pipeline and
|
||||||
a list of PIDs of the processes executing the @var(commands)."
|
a list of PIDs of the processes executing the @var{commands}."
|
||||||
(let* ((to (pipe->fdes))
|
(let* ((to (pipe->fdes))
|
||||||
(pipes (map (lambda _ (pipe->fdes)) commands))
|
(pipes (map (lambda _ (pipe->fdes)) commands))
|
||||||
(pipeline (fold (lambda (from proc prev)
|
(pipeline (fold (lambda (from proc prev)
|
||||||
|
|
|
||||||
|
|
@ -551,7 +551,11 @@ false. It could be that both true and false proofs are available."
|
||||||
(prune-successors analysis label (term-successors term))))
|
(prune-successors analysis label (term-successors term))))
|
||||||
((trivial-intset preds)
|
((trivial-intset preds)
|
||||||
=> (lambda (pred)
|
=> (lambda (pred)
|
||||||
(match (intmap-ref out pred)
|
(match (and (< pred label) (intmap-ref out pred))
|
||||||
|
(#f
|
||||||
|
;; Orphan loop; branch folding must have removed
|
||||||
|
;; entry. Could still be alive though.
|
||||||
|
(visit-term-normally))
|
||||||
(($ $kargs names' vars' ($ $continue _ _ ($ $values vals)))
|
(($ $kargs names' vars' ($ $continue _ _ ($ $values vals)))
|
||||||
;; Substitute dominating definitions, and try to elide the
|
;; Substitute dominating definitions, and try to elide the
|
||||||
;; predecessor entirely.
|
;; predecessor entirely.
|
||||||
|
|
@ -583,7 +587,7 @@ false. It could be that both true and false proofs are available."
|
||||||
;; those as well.
|
;; those as well.
|
||||||
(add-auxiliary-definitions! pred vars substs term-key)))
|
(add-auxiliary-definitions! pred vars substs term-key)))
|
||||||
(visit-term-normally))
|
(visit-term-normally))
|
||||||
(_
|
((or ($ $kclause) ($ $kreceive))
|
||||||
(visit-term-normally)))))
|
(visit-term-normally)))))
|
||||||
(else
|
(else
|
||||||
(visit-term-normally)))))))
|
(visit-term-normally)))))))
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
;;; Continuation-passing style (CPS) intermediate language (IL)
|
;;; Continuation-passing style (CPS) intermediate language (IL)
|
||||||
|
|
||||||
;; Copyright (C) 2013-2015,2017-2019 Free Software Foundation, Inc.
|
;; Copyright (C) 2013-2015,2017-2020 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
|
||||||
|
|
@ -895,37 +895,32 @@
|
||||||
($ (ensure-bytevector klen src op pred bv))))
|
($ (ensure-bytevector klen src op pred bv))))
|
||||||
|
|
||||||
(define (bytevector-ref-converter scheme-name ptr-op width kind)
|
(define (bytevector-ref-converter scheme-name ptr-op width kind)
|
||||||
(define tag
|
(define (tag cps k src val)
|
||||||
(match kind
|
(match kind
|
||||||
('unsigned
|
('unsigned
|
||||||
(if (< (ash 1 (* width 8)) (target-most-positive-fixnum))
|
(if (< (ash 1 (* width 8)) (target-most-positive-fixnum))
|
||||||
(lambda (cps k src val)
|
(with-cps cps
|
||||||
(with-cps cps
|
(letv s)
|
||||||
(letv s)
|
(letk kcvt
|
||||||
(letk kcvt
|
($kargs ('s) (s)
|
||||||
($kargs ('s) (s)
|
($continue k src ($primcall 'tag-fixnum #f (s)))))
|
||||||
($continue k src ($primcall 'tag-fixnum #f (s)))))
|
(build-term
|
||||||
(build-term
|
($continue kcvt src ($primcall 'u64->s64 #f (val)))))
|
||||||
($continue kcvt src ($primcall 'u64->s64 #f (val))))))
|
(with-cps cps
|
||||||
(lambda (cps k src val)
|
(build-term
|
||||||
(with-cps cps
|
($continue k src ($primcall 'u64->scm #f (val)))))))
|
||||||
(build-term
|
|
||||||
($continue k src ($primcall 'u64->scm #f (val))))))))
|
|
||||||
('signed
|
('signed
|
||||||
(if (< (ash 1 (* width 8)) (target-most-positive-fixnum))
|
(if (< (ash 1 (* width 8)) (target-most-positive-fixnum))
|
||||||
(lambda (cps k src val)
|
(with-cps cps
|
||||||
(with-cps cps
|
(build-term
|
||||||
(build-term
|
($continue k src ($primcall 'tag-fixnum #f (val)))))
|
||||||
($continue k src ($primcall 'tag-fixnum #f (val))))))
|
(with-cps cps
|
||||||
(lambda (cps k src val)
|
(build-term
|
||||||
(with-cps cps
|
($continue k src ($primcall 's64->scm #f (val)))))))
|
||||||
(build-term
|
|
||||||
($continue k src ($primcall 's64->scm #f (val))))))))
|
|
||||||
('float
|
('float
|
||||||
(lambda (cps k src val)
|
(with-cps cps
|
||||||
(with-cps cps
|
(build-term
|
||||||
(build-term
|
($continue k src ($primcall 'f64->scm #f (val))))))))
|
||||||
($continue k src ($primcall 'f64->scm #f (val)))))))))
|
|
||||||
(lambda (cps k src op param bv idx)
|
(lambda (cps k src op param bv idx)
|
||||||
(prepare-bytevector-access
|
(prepare-bytevector-access
|
||||||
cps src scheme-name 'bytevector? bv idx width
|
cps src scheme-name 'bytevector? bv idx width
|
||||||
|
|
@ -962,9 +957,9 @@
|
||||||
(build-term
|
(build-term
|
||||||
($branch k' kbad src 'imm-s64-< hi (sval)))))
|
($branch k' kbad src 'imm-s64-< hi (sval)))))
|
||||||
(define (integer-unboxer lo hi)
|
(define (integer-unboxer lo hi)
|
||||||
(cond
|
(lambda (cps src val have-val)
|
||||||
((<= hi (target-most-positive-fixnum))
|
(cond
|
||||||
(lambda (cps src val have-val)
|
((<= hi (target-most-positive-fixnum))
|
||||||
(let ((have-val (if (zero? lo)
|
(let ((have-val (if (zero? lo)
|
||||||
(lambda (cps s)
|
(lambda (cps s)
|
||||||
(with-cps cps
|
(with-cps cps
|
||||||
|
|
@ -989,17 +984,15 @@
|
||||||
($kargs () ()
|
($kargs () ()
|
||||||
($continue klo src ($primcall 'untag-fixnum #f (val)))))
|
($continue klo src ($primcall 'untag-fixnum #f (val)))))
|
||||||
(build-term
|
(build-term
|
||||||
($branch kbad kuntag src 'fixnum? #f (val)))))))
|
($branch kbad kuntag src 'fixnum? #f (val))))))
|
||||||
((zero? lo)
|
((zero? lo)
|
||||||
(lambda (cps src val have-val)
|
|
||||||
(with-cps cps
|
(with-cps cps
|
||||||
(letv u)
|
(letv u)
|
||||||
(let$ body (limit-urange src val u hi have-val))
|
(let$ body (limit-urange src val u hi have-val))
|
||||||
(letk khi ($kargs ('u) (u) ,body))
|
(letk khi ($kargs ('u) (u) ,body))
|
||||||
(build-term
|
(build-term
|
||||||
($continue khi src ($primcall 'scm->u64 #f (val)))))))
|
($continue khi src ($primcall 'scm->u64 #f (val))))))
|
||||||
(else
|
(else
|
||||||
(lambda (cps src val have-val)
|
|
||||||
(with-cps cps
|
(with-cps cps
|
||||||
(letv s)
|
(letv s)
|
||||||
(let$ body (limit-srange src val s lo hi have-val))
|
(let$ body (limit-srange src val s lo hi have-val))
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
;;; srfi-1.scm --- List Library
|
;;; srfi-1.scm --- List Library
|
||||||
|
|
||||||
;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010, 2011, 2014 Free Software Foundation, Inc.
|
;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010, 2011, 2014, 2020 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
|
||||||
|
|
@ -720,6 +720,28 @@ the list returned."
|
||||||
|
|
||||||
;;; Searching
|
;;; Searching
|
||||||
|
|
||||||
|
(define (find pred lst)
|
||||||
|
"Return the first element of @var{lst} that satisfies the predicate
|
||||||
|
@var{pred}, or return @code{#f} if no such element is found."
|
||||||
|
(check-arg procedure? pred find)
|
||||||
|
(let loop ((lst lst))
|
||||||
|
(and (not (null? lst))
|
||||||
|
(let ((head (car lst)))
|
||||||
|
(if (pred head)
|
||||||
|
head
|
||||||
|
(loop (cdr lst)))))))
|
||||||
|
|
||||||
|
(define (find-tail pred lst)
|
||||||
|
"Return the first pair of @var{lst} whose @sc{car} satisfies the
|
||||||
|
predicate @var{pred}, or return @code{#f} if no such element is found."
|
||||||
|
(check-arg procedure? pred find)
|
||||||
|
(let loop ((lst lst))
|
||||||
|
(and (not (null? lst))
|
||||||
|
(let ((head (car lst)))
|
||||||
|
(if (pred head)
|
||||||
|
lst
|
||||||
|
(loop (cdr lst)))))))
|
||||||
|
|
||||||
(define (take-while pred ls)
|
(define (take-while pred ls)
|
||||||
"Return a new list which is the longest initial prefix of LS whose
|
"Return a new list which is the longest initial prefix of LS whose
|
||||||
elements all satisfy the predicate PRED."
|
elements all satisfy the predicate PRED."
|
||||||
|
|
@ -901,6 +923,23 @@ and those making the associations."
|
||||||
|
|
||||||
;;; Delete / assoc / member
|
;;; Delete / assoc / member
|
||||||
|
|
||||||
|
(define* (assoc key alist #:optional (= equal?))
|
||||||
|
"Behaves like @code{assq} but uses third argument @var{pred} for key
|
||||||
|
comparison. If @var{pred} is not supplied, @code{equal?} is
|
||||||
|
used. (Extended from R5RS.)"
|
||||||
|
(cond
|
||||||
|
((eq? = eq?) (assq key alist))
|
||||||
|
((eq? = eqv?) (assv key alist))
|
||||||
|
(else
|
||||||
|
(check-arg procedure? = assoc)
|
||||||
|
(let loop ((alist alist))
|
||||||
|
(and (pair? alist)
|
||||||
|
(let ((item (car alist)))
|
||||||
|
(check-arg pair? item assoc)
|
||||||
|
(if (= key (car item))
|
||||||
|
item
|
||||||
|
(loop (cdr alist)))))))))
|
||||||
|
|
||||||
(define* (member x ls #:optional (= equal?))
|
(define* (member x ls #:optional (= equal?))
|
||||||
(cond
|
(cond
|
||||||
;; This might be performance-sensitive, so punt on the check here,
|
;; This might be performance-sensitive, so punt on the check here,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
;;;; (texinfo) -- parsing of texinfo into SXML
|
;;;; (texinfo) -- parsing of texinfo into SXML
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
|
;;;; Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2020 Free Software Foundation, Inc.
|
||||||
;;;; Copyright (C) 2004, 2009 Andy Wingo <wingo at pobox dot com>
|
;;;; Copyright (C) 2004, 2009 Andy Wingo <wingo at pobox dot com>
|
||||||
;;;; Copyright (C) 2001,2002 Oleg Kiselyov <oleg at pobox dot com>
|
;;;; Copyright (C) 2001,2002 Oleg Kiselyov <oleg at pobox dot com>
|
||||||
;;;;
|
;;;;
|
||||||
|
|
@ -211,6 +211,7 @@ lambda. Only present for @code{INLINE-ARGS}, @code{EOL-ARGS},
|
||||||
(sansserif INLINE-TEXT)
|
(sansserif INLINE-TEXT)
|
||||||
(slanted INLINE-TEXT)
|
(slanted INLINE-TEXT)
|
||||||
(t INLINE-TEXT)
|
(t INLINE-TEXT)
|
||||||
|
(w INLINE-TEXT)
|
||||||
|
|
||||||
;; Inline args commands
|
;; Inline args commands
|
||||||
(value INLINE-ARGS . (key))
|
(value INLINE-ARGS . (key))
|
||||||
|
|
@ -382,7 +383,7 @@ Examples:
|
||||||
;; The % is for arguments
|
;; The % is for arguments
|
||||||
(define (space-significant? command)
|
(define (space-significant? command)
|
||||||
(memq command
|
(memq command
|
||||||
'(example smallexample verbatim lisp smalllisp menu %)))
|
'(example smallexample verbatim lisp smalllisp menu w %)))
|
||||||
|
|
||||||
;; Like a DTD for texinfo
|
;; Like a DTD for texinfo
|
||||||
(define (command-spec command)
|
(define (command-spec command)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
;;;; (texinfo html) -- translating stexinfo into shtml
|
;;;; (texinfo html) -- translating stexinfo into shtml
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
|
;;;; Copyright (C) 2009, 2010, 2011, 2020 Free Software Foundation, Inc.
|
||||||
;;;; Copyright (C) 2003,2004,2009 Andy Wingo <wingo at pobox dot com>
|
;;;; Copyright (C) 2003,2004,2009 Andy Wingo <wingo at pobox dot com>
|
||||||
;;;;
|
;;;;
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
|
|
@ -202,6 +202,7 @@ name, @code{#}, and the node name."
|
||||||
(*fragment* div) ;; should be ok
|
(*fragment* div) ;; should be ok
|
||||||
|
|
||||||
(asis span)
|
(asis span)
|
||||||
|
(w span (@ (class "verbatim")))
|
||||||
(bold b)
|
(bold b)
|
||||||
(i i)
|
(i i)
|
||||||
(sample samp)
|
(sample samp)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
;;;; (web uri) --- URI manipulation tools
|
;;;; (web uri) --- URI manipulation tools
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 1997,2001,2002,2010,2011,2012,2013,2014,2019 Free Software Foundation, Inc.
|
;;;; Copyright (C) 1997,2001,2002,2010,2011,2012,2013,2014,2019,2020 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
|
||||||
|
|
@ -188,7 +188,7 @@ for ‘build-uri’ except there is no scheme."
|
||||||
(define ipv4-regexp
|
(define ipv4-regexp
|
||||||
(make-regexp (string-append "^([" digits ".]+)$")))
|
(make-regexp (string-append "^([" digits ".]+)$")))
|
||||||
(define ipv6-regexp
|
(define ipv6-regexp
|
||||||
(make-regexp (string-append "^([" hex-digits ":.]+)$")))
|
(make-regexp (string-append "^([" hex-digits "]*:[" hex-digits ":.]+)$")))
|
||||||
(define domain-label-regexp
|
(define domain-label-regexp
|
||||||
(make-regexp
|
(make-regexp
|
||||||
(string-append "^[" letters digits "]"
|
(string-append "^[" letters digits "]"
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,29 @@ exec 2>~a; read REPLY"
|
||||||
(close-pipe port)
|
(close-pipe port)
|
||||||
result))))))
|
result))))))
|
||||||
|
|
||||||
|
|
||||||
|
(with-test-prefix "open-pipe*"
|
||||||
|
|
||||||
|
(pass-if-equal "OPEN_BOTH"
|
||||||
|
'(0 (good!))
|
||||||
|
;; This test ensures that the ports that underlie the read/write
|
||||||
|
;; port are unbuffered. If they were buffered, the child process
|
||||||
|
;; would wait in 'read' forever.
|
||||||
|
(let ((pipe (open-pipe* OPEN_BOTH "guile" "-c"
|
||||||
|
(object->string
|
||||||
|
'(begin
|
||||||
|
(setvbuf (current-output-port) 'line)
|
||||||
|
(write '(hello!))
|
||||||
|
(newline)
|
||||||
|
(let ((greeting (read)))
|
||||||
|
(write '(good!))))))))
|
||||||
|
(setvbuf pipe 'line)
|
||||||
|
(let ((return (read pipe)))
|
||||||
|
(write '(hi!) pipe)
|
||||||
|
(newline pipe)
|
||||||
|
(let ((last (read pipe)))
|
||||||
|
(list (close-pipe pipe) last))))))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; close-pipe
|
;; close-pipe
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
;;;; reader.test --- Reader test. -*- coding: iso-8859-1; mode: scheme -*-
|
;;;; reader.test --- Reader test. -*- coding: iso-8859-1; mode: scheme -*-
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 1999, 2001-2003, 2007-2011, 2013-2015
|
;;;; Copyright (C) 1999, 2001-2003, 2007-2011, 2013-2015, 2020
|
||||||
;;;; Free Software Foundation, Inc.
|
;;;; Free Software Foundation, Inc.
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Jim Blandy <jimb@red-bean.com>
|
;;;; Jim Blandy <jimb@red-bean.com>
|
||||||
|
|
@ -40,8 +40,8 @@
|
||||||
(cons 'read-error "end of file in string constant$"))
|
(cons 'read-error "end of file in string constant$"))
|
||||||
(define exception:eof-in-symbol
|
(define exception:eof-in-symbol
|
||||||
(cons 'read-error "end of file while reading symbol$"))
|
(cons 'read-error "end of file while reading symbol$"))
|
||||||
(define exception:illegal-escape
|
(define exception:invalid-escape
|
||||||
(cons 'read-error "illegal character in escape sequence: .*$"))
|
(cons 'read-error "invalid character in escape sequence: .*$"))
|
||||||
(define exception:missing-expression
|
(define exception:missing-expression
|
||||||
(cons 'read-error "no expression after #;"))
|
(cons 'read-error "no expression after #;"))
|
||||||
(define exception:mismatched-paren
|
(define exception:mismatched-paren
|
||||||
|
|
@ -234,8 +234,8 @@
|
||||||
(pass-if-exception "eof in string"
|
(pass-if-exception "eof in string"
|
||||||
exception:eof-in-string
|
exception:eof-in-string
|
||||||
(read-string "\"the string that never ends"))
|
(read-string "\"the string that never ends"))
|
||||||
(pass-if-exception "illegal escape in string"
|
(pass-if-exception "invalid escape in string"
|
||||||
exception:illegal-escape
|
exception:invalid-escape
|
||||||
(read-string "\"some string \\???\"")))
|
(read-string "\"some string \\???\"")))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -304,31 +304,31 @@
|
||||||
|
|
||||||
(with-test-prefix "r6rs-hex-escapes"
|
(with-test-prefix "r6rs-hex-escapes"
|
||||||
(pass-if-exception "non-hex char in two-digit hex-escape"
|
(pass-if-exception "non-hex char in two-digit hex-escape"
|
||||||
exception:illegal-escape
|
exception:invalid-escape
|
||||||
(with-read-options '(r6rs-hex-escapes)
|
(with-read-options '(r6rs-hex-escapes)
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(with-input-from-string "\"\\x0g;\"" read))))
|
(with-input-from-string "\"\\x0g;\"" read))))
|
||||||
|
|
||||||
(pass-if-exception "non-hex char in four-digit hex-escape"
|
(pass-if-exception "non-hex char in four-digit hex-escape"
|
||||||
exception:illegal-escape
|
exception:invalid-escape
|
||||||
(with-read-options '(r6rs-hex-escapes)
|
(with-read-options '(r6rs-hex-escapes)
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(with-input-from-string "\"\\x000g;\"" read))))
|
(with-input-from-string "\"\\x000g;\"" read))))
|
||||||
|
|
||||||
(pass-if-exception "non-hex char in six-digit hex-escape"
|
(pass-if-exception "non-hex char in six-digit hex-escape"
|
||||||
exception:illegal-escape
|
exception:invalid-escape
|
||||||
(with-read-options '(r6rs-hex-escapes)
|
(with-read-options '(r6rs-hex-escapes)
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(with-input-from-string "\"\\x00000g;\"" read))))
|
(with-input-from-string "\"\\x00000g;\"" read))))
|
||||||
|
|
||||||
(pass-if-exception "no semicolon at termination of one-digit hex-escape"
|
(pass-if-exception "no semicolon at termination of one-digit hex-escape"
|
||||||
exception:illegal-escape
|
exception:invalid-escape
|
||||||
(with-read-options '(r6rs-hex-escapes)
|
(with-read-options '(r6rs-hex-escapes)
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(with-input-from-string "\"\\x0\"" read))))
|
(with-input-from-string "\"\\x0\"" read))))
|
||||||
|
|
||||||
(pass-if-exception "no semicolon at termination of three-digit hex-escape"
|
(pass-if-exception "no semicolon at termination of three-digit hex-escape"
|
||||||
exception:illegal-escape
|
exception:invalid-escape
|
||||||
(with-read-options '(r6rs-hex-escapes)
|
(with-read-options '(r6rs-hex-escapes)
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(with-input-from-string "\"\\x000\"" read))))
|
(with-input-from-string "\"\\x000\"" read))))
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
;;;; strings.test --- test suite for Guile's string functions -*- scheme -*-
|
;;;; strings.test --- test suite for Guile's string functions -*- scheme -*-
|
||||||
;;;; Jim Blandy <jimb@red-bean.com> --- August 1999
|
;;;; Jim Blandy <jimb@red-bean.com> --- August 1999
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 1999,2001,2004-2006,2008-2011,2013,2015,2018
|
;;;; Copyright (C) 1999,2001,2004-2006,2008-2011,2013,2015,2018,2020
|
||||||
;;;; 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
|
||||||
|
|
@ -25,8 +25,8 @@
|
||||||
|
|
||||||
(define exception:read-only-string
|
(define exception:read-only-string
|
||||||
(cons 'misc-error "^string is read-only"))
|
(cons 'misc-error "^string is read-only"))
|
||||||
(define exception:illegal-escape
|
(define exception:invalid-escape
|
||||||
(cons 'read-error "illegal character in escape sequence"))
|
(cons 'read-error "invalid character in escape sequence"))
|
||||||
|
|
||||||
;; Create a string from integer char values, eg. (string-ints 65) => "A"
|
;; Create a string from integer char values, eg. (string-ints 65) => "A"
|
||||||
(define (string-ints . args)
|
(define (string-ints . args)
|
||||||
|
|
@ -197,27 +197,27 @@
|
||||||
(with-test-prefix "escapes"
|
(with-test-prefix "escapes"
|
||||||
|
|
||||||
(pass-if-exception "non-hex char in two-digit hex-escape"
|
(pass-if-exception "non-hex char in two-digit hex-escape"
|
||||||
exception:illegal-escape
|
exception:invalid-escape
|
||||||
(with-input-from-string "\"\\x0g\"" read))
|
(with-input-from-string "\"\\x0g\"" read))
|
||||||
|
|
||||||
(pass-if-exception "non-hex char in four-digit hex-escape"
|
(pass-if-exception "non-hex char in four-digit hex-escape"
|
||||||
exception:illegal-escape
|
exception:invalid-escape
|
||||||
(with-input-from-string "\"\\u000g\"" read))
|
(with-input-from-string "\"\\u000g\"" read))
|
||||||
|
|
||||||
(pass-if-exception "non-hex char in six-digit hex-escape"
|
(pass-if-exception "non-hex char in six-digit hex-escape"
|
||||||
exception:illegal-escape
|
exception:invalid-escape
|
||||||
(with-input-from-string "\"\\U00000g\"" read))
|
(with-input-from-string "\"\\U00000g\"" read))
|
||||||
|
|
||||||
(pass-if-exception "premature termination of two-digit hex-escape"
|
(pass-if-exception "premature termination of two-digit hex-escape"
|
||||||
exception:illegal-escape
|
exception:invalid-escape
|
||||||
(with-input-from-string "\"\\x0\"" read))
|
(with-input-from-string "\"\\x0\"" read))
|
||||||
|
|
||||||
(pass-if-exception "premature termination of four-digit hex-escape"
|
(pass-if-exception "premature termination of four-digit hex-escape"
|
||||||
exception:illegal-escape
|
exception:invalid-escape
|
||||||
(with-input-from-string "\"\\u000\"" read))
|
(with-input-from-string "\"\\u000\"" read))
|
||||||
|
|
||||||
(pass-if-exception "premature termination of six-digit hex-escape"
|
(pass-if-exception "premature termination of six-digit hex-escape"
|
||||||
exception:illegal-escape
|
exception:invalid-escape
|
||||||
(with-input-from-string "\"\\U00000\"" read))
|
(with-input-from-string "\"\\U00000\"" read))
|
||||||
|
|
||||||
(pass-if "extra hex digits ignored for two-digit hex escape"
|
(pass-if "extra hex digits ignored for two-digit hex escape"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
;;;; texinfo.test -*- scheme -*-
|
;;;; texinfo.test -*- scheme -*-
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
|
;;;; Copyright (C) 2010, 2011, 2012, 2013, 2014, 2020 Free Software Foundation, Inc.
|
||||||
;;;; Copyright (C) 2001,2002 Oleg Kiselyov <oleg at pobox dot com>
|
;;;; Copyright (C) 2001,2002 Oleg Kiselyov <oleg at pobox dot com>
|
||||||
;;;;
|
;;;;
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
|
|
@ -221,6 +221,8 @@
|
||||||
'((para (code "abc " (code)))))
|
'((para (code "abc " (code)))))
|
||||||
(test-body "@code{ arg }"
|
(test-body "@code{ arg }"
|
||||||
'((para (code "arg"))))
|
'((para (code "arg"))))
|
||||||
|
(test-body "@w{ arg with spaces }"
|
||||||
|
'((para (w " arg with spaces "))))
|
||||||
|
|
||||||
(test-body "@acronym{GNU}"
|
(test-body "@acronym{GNU}"
|
||||||
'((para (acronym (% (acronym "GNU"))))))
|
'((para (acronym (% (acronym "GNU"))))))
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
;;;; web-uri.test --- URI library -*- mode: scheme; coding: utf-8; -*-
|
;;;; web-uri.test --- URI library -*- mode: scheme; coding: utf-8; -*-
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 2010-2012, 2014, 2017, 2019 Free Software Foundation, Inc.
|
;;;; Copyright (C) 2010-2012, 2014, 2017, 2019, 2020 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
|
||||||
|
|
@ -179,6 +179,13 @@
|
||||||
#:port 22
|
#:port 22
|
||||||
#:path "/baz"))
|
#:path "/baz"))
|
||||||
|
|
||||||
|
(pass-if-equal "xyz://abc/x/y/z" ;<https://bugs.gnu.org/40582>
|
||||||
|
(list 'xyz "abc" "/x/y/z")
|
||||||
|
(let ((uri (string->uri "xyz://abc/x/y/z")))
|
||||||
|
(list (uri-scheme uri)
|
||||||
|
(uri-host uri)
|
||||||
|
(uri-path uri))))
|
||||||
|
|
||||||
(pass-if "http://bad.host.1"
|
(pass-if "http://bad.host.1"
|
||||||
(not (string->uri "http://bad.host.1")))
|
(not (string->uri "http://bad.host.1")))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue