Merge github.com:cisco/ChezScheme
original commit: 8118200e237d756f83be54e8bf3eabb4af2388ed
This commit is contained in:
commit
2cf27c4727
84
.travis.yml
84
.travis.yml
|
@ -1,30 +1,62 @@
|
|||
language: c
|
||||
matrix:
|
||||
include:
|
||||
- os: osx
|
||||
env: TARGET_MACHINE=i3osx
|
||||
- os: osx
|
||||
env: TARGET_MACHINE=ti3osx
|
||||
- os: osx
|
||||
env: TARGET_MACHINE=a6osx
|
||||
- os: osx
|
||||
env: TARGET_MACHINE=ta6osx
|
||||
- os: linux
|
||||
env: TARGET_MACHINE=i3le
|
||||
sudo: required
|
||||
- os: linux
|
||||
env: TARGET_MACHINE=ti3le
|
||||
sudo: required
|
||||
- os: linux
|
||||
env: TARGET_MACHINE=a6le
|
||||
- os: linux
|
||||
env: TARGET_MACHINE=ta6le
|
||||
dist: trusty
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-multilib
|
||||
- lib32ncurses5-dev
|
||||
- libx32ncurses5-dev
|
||||
# macOS
|
||||
- env: TARGET_MACHINE=i3osx
|
||||
os: osx
|
||||
- env: TARGET_MACHINE=ti3osx
|
||||
os: osx
|
||||
- env: TARGET_MACHINE=a6osx
|
||||
os: osx
|
||||
- env: TARGET_MACHINE=ta6osx
|
||||
os: osx
|
||||
|
||||
# Linux
|
||||
- env: TARGET_MACHINE=i3le
|
||||
os: linux
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-multilib
|
||||
- lib32ncurses5-dev
|
||||
- libx32ncurses5-dev
|
||||
- uuid-dev:i386
|
||||
- env: TARGET_MACHINE=ti3le
|
||||
os: linux
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-multilib
|
||||
- lib32ncurses5-dev
|
||||
- libx32ncurses5-dev
|
||||
- uuid-dev:i386
|
||||
- env: TARGET_MACHINE=a6le
|
||||
os: linux
|
||||
- env: TARGET_MACHINE=ta6le
|
||||
os: linux
|
||||
|
||||
# Windows
|
||||
- env: TARGET_MACHINE=i3nt
|
||||
os: windows
|
||||
before_script:
|
||||
- git config core.autocrlf false; rm .git/index; git reset --hard
|
||||
- choco install make -y
|
||||
- env: TARGET_MACHINE=ti3nt
|
||||
os: windows
|
||||
before_script:
|
||||
- git config core.autocrlf false; rm .git/index; git reset --hard
|
||||
- choco install make -y
|
||||
- env: TARGET_MACHINE=a6nt
|
||||
os: windows
|
||||
before_script:
|
||||
- git config core.autocrlf false; rm .git/index; git reset --hard
|
||||
- choco install make -y
|
||||
- env: TARGET_MACHINE=ta6nt
|
||||
os: windows
|
||||
before_script:
|
||||
- git config core.autocrlf false; rm .git/index; git reset --hard
|
||||
- choco install make -y
|
||||
dist: xenial
|
||||
script:
|
||||
- .travis/dobuild.sh
|
||||
- .travis/build.sh
|
||||
- .travis/test.sh
|
||||
|
|
15
.travis/build.sh
Executable file
15
.travis/build.sh
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
set -e -o pipefail
|
||||
echo 'travis_fold:start:build'
|
||||
echo Building Chez Scheme...
|
||||
./configure -m=$TARGET_MACHINE
|
||||
make
|
||||
case $TARGET_MACHINE in
|
||||
*a6nt)
|
||||
curl -Ls https://github.com/burgerrg/win-iconv/releases/download/v0.0.9/iconv-x64.dll > $TARGET_MACHINE/bin/$TARGET_MACHINE/iconv.dll
|
||||
;;
|
||||
*i3nt)
|
||||
curl -Ls https://github.com/burgerrg/win-iconv/releases/download/v0.0.9/iconv-x86.dll > $TARGET_MACHINE/bin/$TARGET_MACHINE/iconv.dll
|
||||
;;
|
||||
esac
|
||||
echo 'travis_fold:end:build'
|
|
@ -1,27 +0,0 @@
|
|||
#!/bin/bash
|
||||
case $TARGET_MACHINE in
|
||||
*i3le) sudo apt-get -yq --no-install-suggests --no-install-recommends install uuid-dev:i386 ;;
|
||||
*)
|
||||
esac
|
||||
./configure -m=$TARGET_MACHINE
|
||||
exitcode=$?
|
||||
if [ $exitcode -ne 0 ] ; then
|
||||
echo "Failed: configure step"
|
||||
exit $exitcode
|
||||
fi
|
||||
make
|
||||
exitcode=$?
|
||||
if [ $exitcode -ne 0 ] ; then
|
||||
echo "Failed: make step"
|
||||
exit $exitcode
|
||||
fi
|
||||
( cd ${TARGET_MACHINE}/mats && make partialx 2>&1 ) | tee Make.out | grep '^matting '
|
||||
diff -q .travis/summary ${TARGET_MACHINE}/mats/summary
|
||||
exitcode=$?
|
||||
|
||||
if [ $exitcode -ne 0 ] ; then
|
||||
echo "Failed: testing step"
|
||||
echo "mats summary:"
|
||||
cat ${TARGET_MACHINE}/mats/summary
|
||||
exit $exitcode
|
||||
fi
|
21
.travis/test.sh
Executable file
21
.travis/test.sh
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
runmats() {
|
||||
echo travis_fold:start:mats
|
||||
echo make allxhelp "$@"
|
||||
make -C ${TARGET_MACHINE}/mats allxhelp "$@" 2>&1 | tee -a Make.out | grep '^matting '
|
||||
echo travis_fold:end:mats
|
||||
}
|
||||
|
||||
# Split these out so that we get output every 10 minutes on Windows builds.
|
||||
runmats o=0
|
||||
runmats o=3
|
||||
runmats o=3 cp0=t
|
||||
runmats o=3 cp0=t eval=interpret
|
||||
|
||||
if [ -f ${TARGET_MACHINE}/mats/summary ]; then
|
||||
cat ${TARGET_MACHINE}/mats/summary
|
||||
diff -q .travis/summary ${TARGET_MACHINE}/mats/summary
|
||||
exit $?
|
||||
else
|
||||
exit 1
|
||||
fi
|
17
BUILDING
17
BUILDING
|
@ -196,19 +196,20 @@ The make file supports several targets:
|
|||
|
||||
WINDOWS
|
||||
|
||||
Building Chez Scheme under 64-bit Windows with Cygwin or Bash/WSL
|
||||
follows the instructions above, except that 'make install' and 'make
|
||||
uninstall' are not supported. On Bash/WSL, the build directory must be
|
||||
in a location with a Windows path such as /mnt/c, and the 'OS'
|
||||
environment variable must be set to 'Windows_NT' to indicate a build
|
||||
for Windows, as opposed to a build for Linux on Windows:
|
||||
Building Chez Scheme under 64-bit Windows with Bash/WSL, MinGW/MSYS,
|
||||
or Cygwin follows the instructions above, except that 'make install'
|
||||
and 'make uninstall' are not supported. On Bash/WSL, the build
|
||||
directory must be in a location with a Windows path such as /mnt/c,
|
||||
and the 'OS' environment variable must be set to 'Windows_NT' to
|
||||
indicate a build for Windows, as opposed to a build for Linux on
|
||||
Windows:
|
||||
|
||||
env OS=Windows_NT ./configure
|
||||
env OS=Windows_NT make
|
||||
|
||||
Prerequisites:
|
||||
|
||||
* Cygwin or Bash/WSL with bash, git, grep, make, sed, etc.
|
||||
* Bash/WSL, MinGW/MSYS, or Cygwin with bash, git, grep, make, sed, etc.
|
||||
* Microsoft Visual Studio 2017 or 2015
|
||||
* WiX Toolset (for making an install)
|
||||
|
||||
|
@ -251,7 +252,7 @@ http://gnuwin32.sourceforge.net/packages/libiconv.htm
|
|||
|
||||
An alternative that uses the Windows API can be found at:
|
||||
|
||||
https://github.com/win-iconv/win-iconv
|
||||
https://github.com/burgerrg/win-iconv/releases
|
||||
|
||||
If the DLL is not present, the iconv tests will fail. No other tests
|
||||
should be affected.
|
||||
|
|
100
LOG
100
LOG
|
@ -1313,5 +1313,101 @@
|
|||
externs.h, system.h, expeditor.c, configure, Mf-*, Makefile.*nt,
|
||||
workarea, mat.ss, io.ms, io.stex, objects.stex, release_notes.stex,
|
||||
root-experr*, patch*
|
||||
- fix multiply of most negative fixnum to itself on 64-bit platforms
|
||||
number.c, 5_3.ms
|
||||
- added compress-level parameter to select a compression level for
|
||||
file writing and changed the default for lz4 compression to do a
|
||||
better job compressing. finished splitting glz input routines
|
||||
apart from glz output routines and did a bit of other restructuring.
|
||||
removed gzxfile struct-as-bytevector wrapper and moved its fd
|
||||
into glzFile. moved DEACTIVATE to before glzdopen_input calls
|
||||
in S_new_open_input_fd and S_compress_input_fd, since glzdopen_input
|
||||
reads from the file and could block. the compress format and now
|
||||
level are now recorded directly the thread context. replaced
|
||||
as-gz? flag bit in compressed bytevector header word with a small
|
||||
number of bits recording the compression format at the bottom of
|
||||
the header word. flushed a couple of bytevector compression mats
|
||||
that depended on the old representation. (these last few changes
|
||||
should make adding new compression formats easier.) added
|
||||
s-directory build options to choose whether to compress and, if
|
||||
so, the format and level.
|
||||
compress-io.h, compress-io.c, new-io.c, equates.h, system.h,
|
||||
scheme.c, gc.c,
|
||||
io.ss, cmacros.ss, back.ss, bytevector.ss, primdata.ss, s/Mf-base,
|
||||
io.ms, mat.ss, bytevector.ms, root-experr*,
|
||||
release_notes.stex, io.stex, system.stex, objects.stex
|
||||
- improved the effectiveness of LZ4 boot-file compression to within
|
||||
15% of gzip by increasing the lz4 output-port in_buffer size to
|
||||
1<<18. With the previous size (1<<14) LZ4-compressed boot files
|
||||
were about 50% larger. set the lz4 input-port in_buffer and
|
||||
out_buffer sizes to 1<<12 and 1<<14. there's no clear win at
|
||||
present for larger input-port buffer sizes.
|
||||
compress-io.c
|
||||
- To reduce the memory hit for the increased output-port in_buffer
|
||||
size and the corresponding increase in computed out_buffer size,
|
||||
one output-side out_buffer is now allocated (lazily) per thread
|
||||
and stored in the thread context. The other buffers are now
|
||||
directly a part of the lz4File_out and lz4File_in structures
|
||||
rather than allocated separately.
|
||||
compress-io.c, scheme.c, gc.c,
|
||||
cmacros.ss
|
||||
- split out the buffer emit code from glzwrite_lz4 into a
|
||||
separate glzemit_lz4 helper that is now also used by gzclose
|
||||
so we can avoid dealing with a NULL buffer in glzwrite_lz4.
|
||||
glzwrite_lz4 also uses it to writing large buffers directly and
|
||||
avoid the memcpy.
|
||||
compress-io.c
|
||||
- replaced lz4File_out and lz4File_in mode enumeration with the
|
||||
compress format and inputp boolean. using switch to check and
|
||||
raising exceptions for unexpected values to further simplify
|
||||
adding new compression formats in the future.
|
||||
compress-io.c
|
||||
- replaced the never-defined struct lz4File pointer in glzFile
|
||||
union with the more specific struct lz4File_in_r and Lz4File_out_r
|
||||
pointers.
|
||||
compress-io.h, compress-io.c
|
||||
- added free of lz4 structures to gzclose. also changed file-close
|
||||
logic generally so that (1) port is marked closed before anything is
|
||||
freed to avoid dangling pointers in the case of an interrupt or
|
||||
error, and (2) structures are freed even in the case of a write
|
||||
or close error, before the error is reported. also now mallocing
|
||||
glz and lz4 structures after possibility of errors have passed where
|
||||
possible and freeing them when not.
|
||||
compress-io.c,
|
||||
io.ss
|
||||
- added return-value checks to malloc calls and to a couple of other
|
||||
C-library calls.
|
||||
compress-io.c
|
||||
- corrected EINTR checks to look at errno rather than return codes.
|
||||
compress-io.c
|
||||
- added S_ prefixes to the glz* exports
|
||||
externs.h, compress-io.c, new-io.c, scheme.c, fasl.c
|
||||
- added entries for mutex-name and mutex-thread
|
||||
threads.stex
|
||||
- fix record-ref reduction in cp0
|
||||
in expressions like
|
||||
(record-ref ... (begin (newline) (record ...)))
|
||||
the reduction was dropping the possible side effect expressions
|
||||
in this case the (newline).
|
||||
cp0.ss
|
||||
- zero?, fxzero?, positive?, fxpositive?, etc., now go through
|
||||
(a suitably modified) relop-length so that, for example,
|
||||
(zero? (length x)) results in the same code as (null? x). added
|
||||
correctness tests for these and all of the other predicates that
|
||||
go through relop-length.
|
||||
cpnanopass.ss, 5_2.ms
|
||||
- assertion-violationf and friends now show the who, message, and
|
||||
irritants in the original call when who or message is found not to
|
||||
be of the right type.
|
||||
exceptions.ss
|
||||
- fix incorrect uses of fxzero? x86.ss backend, since a 32-bit
|
||||
immediate is not necessarily a fixnum
|
||||
x86.ss
|
||||
- added MinGW/MSYS build support for Windows and configuration for
|
||||
Travis-CI testing of all Windows builds
|
||||
BUILDING, .travis*, wininstall/Makefile
|
||||
- fix multiply of -2^30 with itself on 64-bit platforms
|
||||
number.c, 5_3.ms, release_notes.stex
|
||||
- fixed typo in description of case macro
|
||||
csug/control.stex
|
||||
- fix signatures of $annotation-options, $fasl-strip-options,
|
||||
$file-options, and $library-requirements-options
|
||||
primdata.ss
|
||||
|
|
962
c/compress-io.c
962
c/compress-io.c
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
/* compress-io.h
|
||||
* Copyright 1984-2017 Cisco Systems, Inc.
|
||||
* Copyright 1984-2019 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,34 +14,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "zlib.h"
|
||||
|
||||
struct lz4File;
|
||||
|
||||
typedef struct glzFile_r {
|
||||
int mode;
|
||||
INT fd;
|
||||
IBOOL inputp;
|
||||
INT format;
|
||||
union {
|
||||
gzFile gz;
|
||||
struct lz4File *lz4;
|
||||
struct gzFile_s *gz;
|
||||
struct lz4File_in_r *lz4_in;
|
||||
struct lz4File_out_r *lz4_out;
|
||||
};
|
||||
} *glzFile;
|
||||
|
||||
glzFile glzdopen_gz(int fd, const char *mode);
|
||||
glzFile glzdopen_lz4(int fd, const char *mode);
|
||||
glzFile glzdopen(int fd, const char *mode);
|
||||
glzFile glzopen(const char *path, const char *mode);
|
||||
#ifdef WIN32
|
||||
glzFile glzopen_w(wchar_t *path, const char *mode);
|
||||
#endif
|
||||
int glzdirect(glzFile file);
|
||||
int glzclose(glzFile file);
|
||||
|
||||
int glzread(glzFile file, void *buffer, unsigned int count);
|
||||
int glzwrite(glzFile file, void *buffer, unsigned int count);
|
||||
long glzseek(glzFile file, long offset, int whence);
|
||||
int glzgetc(glzFile file);
|
||||
int glzungetc(int c, glzFile file);
|
||||
int glzrewind(glzFile file);
|
||||
|
||||
void glzerror(glzFile file, int *errnum);
|
||||
void glzclearerr(glzFile fdfile);
|
||||
|
|
31
c/externs.h
31
c/externs.h
|
@ -184,6 +184,27 @@ extern wchar_t *S_malloc_wide_pathname PROTO((const char *inpath));
|
|||
#endif
|
||||
extern IBOOL S_fixedpathp PROTO((const char *inpath));
|
||||
|
||||
/* compress-io.c */
|
||||
extern glzFile S_glzdopen_output PROTO((INT fd, INT compress_format, INT compress_level));
|
||||
extern glzFile S_glzdopen_input PROTO((INT fd));
|
||||
extern glzFile S_glzopen_input PROTO((const char *path));
|
||||
#ifdef WIN32
|
||||
extern glzFile S_glzopen_input_w PROTO((const wchar_t *path));
|
||||
#endif
|
||||
extern IBOOL S_glzdirect PROTO((glzFile file));
|
||||
extern INT S_glzclose PROTO((glzFile file));
|
||||
|
||||
extern INT S_glzread PROTO((glzFile file, void *buffer, UINT count));
|
||||
extern INT S_glzwrite PROTO((glzFile file, void *buffer, UINT count));
|
||||
extern long S_glzseek PROTO((glzFile file, long offset, INT whence));
|
||||
extern INT S_glzgetc PROTO((glzFile file));
|
||||
extern INT S_glzungetc PROTO((INT c, glzFile file));
|
||||
extern INT S_glzrewind PROTO((glzFile file));
|
||||
|
||||
extern void S_glzerror PROTO((glzFile file, INT *errnum));
|
||||
extern void S_glzclearerr PROTO((glzFile fdfile));
|
||||
|
||||
|
||||
/* new-io.c */
|
||||
extern INT S_gzxfile_fd PROTO((ptr x));
|
||||
extern glzFile S_gzxfile_gzfile PROTO((ptr x));
|
||||
|
@ -191,14 +212,14 @@ extern ptr S_new_open_input_fd PROTO((const char *filename, IBOOL compressed));
|
|||
extern ptr S_new_open_output_fd PROTO((
|
||||
const char *filename, INT mode,
|
||||
IBOOL no_create, IBOOL no_fail, IBOOL no_truncate,
|
||||
IBOOL append, IBOOL lock, IBOOL replace, IBOOL compressed, IBOOL as_gz));
|
||||
IBOOL append, IBOOL lock, IBOOL replace, IBOOL compressed));
|
||||
extern ptr S_new_open_input_output_fd PROTO((
|
||||
const char *filename, INT mode,
|
||||
IBOOL no_create, IBOOL no_fail, IBOOL no_truncate,
|
||||
IBOOL append, IBOOL lock, IBOOL replace, IBOOL compressed));
|
||||
extern ptr S_close_fd PROTO((ptr file, IBOOL gzflag));
|
||||
extern ptr S_compress_input_fd PROTO((INT fd, I64 fp));
|
||||
extern ptr S_compress_output_fd PROTO((INT fd, IBOOL as_gz));
|
||||
extern ptr S_compress_output_fd PROTO((INT fd));
|
||||
|
||||
extern ptr S_bytevector_read PROTO((ptr file, ptr buffer, iptr start, iptr count, IBOOL gzflag));
|
||||
extern ptr S_bytevector_read_nb PROTO((ptr file, ptr buffer, iptr start, iptr count, IBOOL gzflag));
|
||||
|
@ -213,13 +234,13 @@ extern ptr S_get_fd_length PROTO((ptr file, IBOOL gzflag));
|
|||
extern ptr S_set_fd_length PROTO((ptr file, ptr length, IBOOL gzflag));
|
||||
extern void S_new_io_init PROTO((void));
|
||||
|
||||
extern uptr S_bytevector_compress_size PROTO((iptr s_count, IBOOL as_gz));
|
||||
extern uptr S_bytevector_compress_size PROTO((iptr s_count, INT compress_format));
|
||||
extern ptr S_bytevector_compress PROTO((ptr dest_bv, iptr d_start, iptr d_count,
|
||||
ptr src_bv, iptr s_start, iptr s_count,
|
||||
IBOOL as_gz));
|
||||
INT compress_format));
|
||||
extern ptr S_bytevector_uncompress PROTO((ptr dest_bv, iptr d_start, iptr d_count,
|
||||
ptr src_bv, iptr s_start, iptr s_count,
|
||||
IBOOL as_gz));
|
||||
INT compress_format));
|
||||
|
||||
/* thread.c */
|
||||
extern void S_thread_init PROTO((void));
|
||||
|
|
7
c/fasl.c
7
c/fasl.c
|
@ -177,6 +177,7 @@
|
|||
*/
|
||||
|
||||
#include "system.h"
|
||||
#include "zlib.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
|
@ -346,14 +347,14 @@ static INT uf_read(unbufFaslFile uf, octet *s, iptr n) {
|
|||
|
||||
switch (uf->type) {
|
||||
case UFFO_TYPE_GZ:
|
||||
k = glzread(uf->file, s, (GZ_IO_SIZE_T)nx);
|
||||
k = S_glzread(uf->file, s, (GZ_IO_SIZE_T)nx);
|
||||
if (k > 0)
|
||||
n -= k;
|
||||
else if (k == 0)
|
||||
return -1;
|
||||
else {
|
||||
glzerror(uf->file, &errnum);
|
||||
glzclearerr(uf->file);
|
||||
S_glzerror(uf->file, &errnum);
|
||||
S_glzclearerr(uf->file);
|
||||
if (errnum != Z_ERRNO || errno != EINTR)
|
||||
S_error1("", "error reading from ~a", uf->path);
|
||||
}
|
||||
|
|
3
c/gc.c
3
c/gc.c
|
@ -1894,6 +1894,9 @@ static void sweep_thread(p) ptr p; {
|
|||
/* immediate SUPPRESSPRIMITIVEINLINING */
|
||||
relocate(&DEFAULTRECORDEQUALPROCEDURE(tc))
|
||||
relocate(&DEFAULTRECORDHASHPROCEDURE(tc))
|
||||
relocate(&COMPRESSFORMAT(tc))
|
||||
relocate(&COMPRESSLEVEL(tc))
|
||||
/* void* LZ4OUTBUFFER(tc) */
|
||||
/* U64 INSTRCOUNTER(tc) */
|
||||
/* U64 ALLOCCOUNTER(tc) */
|
||||
relocate(&PARAMETERS(tc))
|
||||
|
|
271
c/new-io.c
271
c/new-io.c
|
@ -52,9 +52,8 @@
|
|||
/* locally defined functions */
|
||||
static ptr new_open_output_fd_helper PROTO((const char *filename, INT mode,
|
||||
INT flags, INT no_create, INT no_fail, INT no_truncate,
|
||||
INT append, INT lock, INT replace, INT compressed, INT as_gz));
|
||||
INT append, INT lock, INT replace, INT compressed));
|
||||
static INT lockfile PROTO((INT fd));
|
||||
static ptr make_gzxfile PROTO((int fd, glzFile file));
|
||||
static int is_valid_zlib_length(iptr count);
|
||||
static int is_valid_lz4_length(iptr count);
|
||||
|
||||
|
@ -78,8 +77,8 @@ static int is_valid_lz4_length(iptr count);
|
|||
if (ok) { flag = 0; } \
|
||||
else { \
|
||||
INT errnum; \
|
||||
glzerror((fd),&errnum); \
|
||||
glzclearerr((fd)); \
|
||||
S_glzerror((fd),&errnum); \
|
||||
S_glzclearerr((fd)); \
|
||||
if (errnum == Z_ERRNO) { \
|
||||
flag = errno != EINTR; \
|
||||
} else { \
|
||||
|
@ -99,8 +98,8 @@ static int is_valid_lz4_length(iptr count);
|
|||
if (ok) { flag = 0; break; } \
|
||||
else { \
|
||||
INT errnum; \
|
||||
glzerror((fd),&errnum); \
|
||||
glzclearerr((fd)); \
|
||||
S_glzerror((fd),&errnum); \
|
||||
S_glzclearerr((fd)); \
|
||||
if (errnum == Z_ERRNO) { \
|
||||
if (errno != EINTR) { flag = 1; break; } \
|
||||
} else { \
|
||||
|
@ -117,8 +116,8 @@ static int is_valid_lz4_length(iptr count);
|
|||
if (ok) { flag = 0; } \
|
||||
else { \
|
||||
INT errnum; \
|
||||
glzerror((fd),&errnum); \
|
||||
glzclearerr((fd)); \
|
||||
S_glzerror((fd),&errnum); \
|
||||
S_glzclearerr((fd)); \
|
||||
if (errnum == Z_ERRNO) { flag = 1; } \
|
||||
else { \
|
||||
flag = not_ok_is_fatal || errnum != Z_OK; \
|
||||
|
@ -145,26 +144,15 @@ static INT lockfile(INT fd) { return FLOCK(fd, LOCK_EX); }
|
|||
static INT lockfile(INT fd) { return lockf(fd, F_LOCK, (off_t)0); }
|
||||
#endif
|
||||
|
||||
/* work around missing zlib API operation to extract a glzFile's fd */
|
||||
typedef struct {
|
||||
int fd;
|
||||
glzFile file;
|
||||
} gzxfile;
|
||||
#define gzxfile_fd(x) (((gzxfile *)&BVIT(x,0))->fd)
|
||||
#define gzxfile_gzfile(x) (((gzxfile *)&BVIT(x,0))->file)
|
||||
static ptr make_gzxfile(int fd, glzFile file) {
|
||||
ptr bv;
|
||||
#define MAKE_GZXFILE(x) Sinteger((iptr)x)
|
||||
#define GZXFILE_GZFILE(x) ((glzFile)Sinteger_value(x))
|
||||
|
||||
bv = S_bytevector(sizeof(gzxfile));
|
||||
gzxfile_fd(bv) = fd;
|
||||
gzxfile_gzfile(bv) = file;
|
||||
return bv;
|
||||
}
|
||||
INT S_gzxfile_fd(ptr x) {
|
||||
return gzxfile_fd(x);
|
||||
return GZXFILE_GZFILE(x)->fd;
|
||||
}
|
||||
|
||||
glzFile S_gzxfile_gzfile(ptr x) {
|
||||
return gzxfile_gzfile(x);
|
||||
return GZXFILE_GZFILE(x);
|
||||
}
|
||||
|
||||
ptr S_new_open_input_fd(const char *infilename, IBOOL compressed) {
|
||||
|
@ -209,25 +197,26 @@ ptr S_new_open_input_fd(const char *infilename, IBOOL compressed) {
|
|||
return Scons(FIX(OPEN_ERROR_OTHER), str);
|
||||
}
|
||||
|
||||
if ((file = glzdopen(dupfd, "rb")) == Z_NULL) {
|
||||
DEACTIVATE(tc) /* glzdopen_input reads the magic word from the file */
|
||||
if ((file = S_glzdopen_input(dupfd)) == Z_NULL) {
|
||||
REACTIVATE(tc)
|
||||
FD_GUARD(result == 0, error, result = CLOSE(fd));
|
||||
FD_GUARD(result == 0, error, result = CLOSE(dupfd));
|
||||
return Scons(FIX(OPEN_ERROR_OTHER), Sstring("unable to allocate compression state (too many open files?)"));
|
||||
}
|
||||
|
||||
DEACTIVATE(tc)
|
||||
compressed = !glzdirect(file);
|
||||
compressed = !S_glzdirect(file);
|
||||
REACTIVATE(tc)
|
||||
|
||||
if (compressed) {
|
||||
FD_GUARD(result == 0, error, result = CLOSE(fd));
|
||||
/* box indicates gzip'd */
|
||||
return Sbox(make_gzxfile(dupfd, file));
|
||||
/* box indicates compressed */
|
||||
return Sbox(MAKE_GZXFILE(file));
|
||||
}
|
||||
|
||||
GZ_GUARD(1, ok == 0 || ok == Z_BUF_ERROR, flag, file, ok = glzclose(file));
|
||||
GZ_GUARD(1, ok == 0 || ok == Z_BUF_ERROR, flag, file, ok = S_glzclose(file));
|
||||
if (flag) {} /* make the compiler happy */
|
||||
if (LSEEK(fd, 0, SEEK_SET) != 0) { /* glzdirect does not leave fd at position 0 */
|
||||
if (LSEEK(fd, 0, SEEK_SET) != 0) { /* glzdopen and glzdirect might not leave fd at position 0 */
|
||||
FD_GUARD(result == 0, error, result = CLOSE(fd));
|
||||
return Scons(FIX(OPEN_ERROR_OTHER),Sstring("unable to reset after reading header bytes"));
|
||||
}
|
||||
|
@ -245,22 +234,24 @@ ptr S_compress_input_fd(INT fd, I64 pos) {
|
|||
return S_strerror(errno);
|
||||
}
|
||||
|
||||
if ((file = glzdopen(dupfd, "rb")) == Z_NULL) {
|
||||
DEACTIVATE(tc)
|
||||
if ((file = S_glzdopen_input(dupfd)) == Z_NULL) {
|
||||
REACTIVATE(tc)
|
||||
FD_GUARD(result == 0, error, result = CLOSE(dupfd));
|
||||
return Sstring("unable to allocate compression state (too many open files?)");
|
||||
}
|
||||
|
||||
DEACTIVATE(tc)
|
||||
compressed = !glzdirect(file);
|
||||
compressed = !S_glzdirect(file);
|
||||
REACTIVATE(tc)
|
||||
|
||||
if (compressed) {
|
||||
FD_GUARD(result == 0, error, result = CLOSE(fd));
|
||||
if (error) {} /* make the compiler happy */
|
||||
return Sbox(make_gzxfile(dupfd, file));
|
||||
/* box indicates compressed */
|
||||
return Sbox(MAKE_GZXFILE(file));
|
||||
}
|
||||
|
||||
GZ_GUARD(1, ok == 0 || ok == Z_BUF_ERROR, flag, file, ok = glzclose(file));
|
||||
GZ_GUARD(1, ok == 0 || ok == Z_BUF_ERROR, flag, file, ok = S_glzclose(file));
|
||||
if (flag) {} /* make the compiler happy */
|
||||
if (LSEEK(fd, pos, SEEK_SET) != pos) { /* glzdirect does not leave fd at same position */
|
||||
return Sstring("unable to reset after reading header bytes");
|
||||
|
@ -268,38 +259,28 @@ ptr S_compress_input_fd(INT fd, I64 pos) {
|
|||
return MAKE_FD(fd);
|
||||
}
|
||||
|
||||
ptr S_compress_output_fd(INT fd, IBOOL as_gz) {
|
||||
ptr S_compress_output_fd(INT fd) {
|
||||
glzFile file;
|
||||
int as_append;
|
||||
ptr tc = get_thread_context();
|
||||
|
||||
#ifdef WIN32
|
||||
as_append = 0;
|
||||
#else
|
||||
as_append = fcntl(fd, F_GETFL) & O_APPEND;
|
||||
#endif
|
||||
|
||||
if (as_gz)
|
||||
file = glzdopen_gz(fd, as_append ? "ab" : "wb");
|
||||
else
|
||||
file = glzdopen_lz4(fd, as_append ? "ab" : "wb");
|
||||
file = S_glzdopen_output(fd, (INT)UNFIX(COMPRESSFORMAT(tc)), (INT)UNFIX(COMPRESSLEVEL(tc)));
|
||||
|
||||
if (file == Z_NULL)
|
||||
return Sstring("unable to allocate compression state (too many open files?)");
|
||||
|
||||
return Sbox(make_gzxfile(fd, file));
|
||||
/* box indicates compressed */
|
||||
return Sbox(MAKE_GZXFILE(file));
|
||||
}
|
||||
|
||||
static ptr new_open_output_fd_helper(
|
||||
const char *infilename, INT mode, INT flags,
|
||||
IBOOL no_create, IBOOL no_fail, IBOOL no_truncate,
|
||||
IBOOL append, IBOOL lock, IBOOL replace, IBOOL compressed, IBOOL as_gz) {
|
||||
IBOOL append, IBOOL lock, IBOOL replace, IBOOL compressed) {
|
||||
char *filename;
|
||||
INT saved_errno = 0;
|
||||
iptr error;
|
||||
INT fd, result;
|
||||
#ifdef PTHREADS
|
||||
ptr tc = get_thread_context();
|
||||
#endif
|
||||
|
||||
flags |=
|
||||
(no_create ? 0 : O_CREAT) |
|
||||
|
@ -358,26 +339,23 @@ static ptr new_open_output_fd_helper(
|
|||
}
|
||||
|
||||
glzFile file;
|
||||
if (as_gz)
|
||||
file = glzdopen_gz(fd, append ? "ab" : "wb");
|
||||
else
|
||||
file = glzdopen_lz4(fd, append ? "ab" : "wb");
|
||||
file = S_glzdopen_output(fd, (INT)UNFIX(COMPRESSFORMAT(tc)), (INT)UNFIX(COMPRESSLEVEL(tc)));
|
||||
if (file == Z_NULL) {
|
||||
FD_GUARD(result == 0, error, result = CLOSE(fd));
|
||||
return Scons(FIX(OPEN_ERROR_OTHER), Sstring("unable to allocate compression state"));
|
||||
}
|
||||
|
||||
return make_gzxfile(fd, file);
|
||||
return MAKE_GZXFILE(file);
|
||||
}
|
||||
|
||||
ptr S_new_open_output_fd(
|
||||
const char *filename, INT mode,
|
||||
IBOOL no_create, IBOOL no_fail, IBOOL no_truncate,
|
||||
IBOOL append, IBOOL lock, IBOOL replace, IBOOL compressed, IBOOL as_gz) {
|
||||
IBOOL append, IBOOL lock, IBOOL replace, IBOOL compressed) {
|
||||
return new_open_output_fd_helper(
|
||||
filename, mode, O_BINARY | O_WRONLY,
|
||||
no_create, no_fail, no_truncate,
|
||||
append, lock, replace, compressed, as_gz);
|
||||
append, lock, replace, compressed);
|
||||
}
|
||||
|
||||
ptr S_new_open_input_output_fd(
|
||||
|
@ -390,14 +368,14 @@ ptr S_new_open_input_output_fd(
|
|||
return new_open_output_fd_helper(
|
||||
filename, mode, O_BINARY | O_RDWR,
|
||||
no_create, no_fail, no_truncate,
|
||||
append, lock, replace, compressed, 0);
|
||||
append, lock, replace, 0);
|
||||
}
|
||||
|
||||
ptr S_close_fd(ptr file, IBOOL gzflag) {
|
||||
INT saved_errno = 0;
|
||||
INT ok, flag;
|
||||
INT fd = gzflag ? 0 : GET_FD(file);
|
||||
glzFile gzfile = gzflag ? gzxfile_gzfile(file) : NULL;
|
||||
glzFile gzfile = gzflag ? GZXFILE_GZFILE(file) : NULL;
|
||||
#ifdef PTHREADS
|
||||
ptr tc = get_thread_context();
|
||||
#endif
|
||||
|
@ -414,7 +392,7 @@ ptr S_close_fd(ptr file, IBOOL gzflag) {
|
|||
FD_GUARD(ok == 0, flag, ok = CLOSE(fd));
|
||||
} else {
|
||||
/* zlib 1.2.1 returns Z_BUF_ERROR when closing an empty file opened for reading */
|
||||
GZ_GUARD(1, ok == 0 || ok == Z_BUF_ERROR, flag, gzfile, ok = glzclose(gzfile));
|
||||
GZ_GUARD(1, ok == 0 || ok == Z_BUF_ERROR, flag, gzfile, ok = S_glzclose(gzfile));
|
||||
}
|
||||
saved_errno = errno;
|
||||
REACTIVATE(tc)
|
||||
|
@ -444,7 +422,7 @@ ptr S_bytevector_read(ptr file, ptr bv, iptr start, iptr count, IBOOL gzflag) {
|
|||
ptr tc = get_thread_context();
|
||||
iptr m, flag = 0;
|
||||
INT fd = gzflag ? 0 : GET_FD(file);
|
||||
glzFile gzfile = gzflag ? gzxfile_gzfile(file) : NULL;
|
||||
glzFile gzfile = gzflag ? GZXFILE_GZFILE(file) : NULL;
|
||||
|
||||
/* file is not locked; do not reference after deactivating thread! */
|
||||
file = (ptr)-1;
|
||||
|
@ -477,7 +455,7 @@ ptr S_bytevector_read(ptr file, ptr bv, iptr start, iptr count, IBOOL gzflag) {
|
|||
GZ_EINTR_GUARD(
|
||||
1, m >= 0 || Sboolean_value(KEYBOARDINTERRUPTPENDING(tc)),
|
||||
flag, gzfile,
|
||||
m = glzread(gzfile, &BVIT(bv,start), (GZ_IO_SIZE_T)count));
|
||||
m = S_glzread(gzfile, &BVIT(bv,start), (GZ_IO_SIZE_T)count));
|
||||
}
|
||||
}
|
||||
saved_errno = errno;
|
||||
|
@ -561,7 +539,7 @@ ptr S_bytevector_write(ptr file, ptr bv, iptr start, iptr count, IBOOL gzflag) {
|
|||
ptr tc = get_thread_context();
|
||||
INT flag = 0, saved_errno = 0;
|
||||
INT fd = gzflag ? 0 : GET_FD(file);
|
||||
glzFile gzfile = gzflag ? gzxfile_gzfile(file) : NULL;
|
||||
glzFile gzfile = gzflag ? GZXFILE_GZFILE(file) : NULL;
|
||||
|
||||
for (s = start, c = count; c > 0; s += i, c -= i) {
|
||||
iptr cx = c;
|
||||
|
@ -579,7 +557,7 @@ ptr S_bytevector_write(ptr file, ptr bv, iptr start, iptr count, IBOOL gzflag) {
|
|||
GZ_EINTR_GUARD(
|
||||
i < 0, i > 0 || Sboolean_value(KEYBOARDINTERRUPTPENDING(tc)),
|
||||
flag, gzfile,
|
||||
i = glzwrite(gzfile, &BVIT(bv,s), (GZ_IO_SIZE_T)cx));
|
||||
i = S_glzwrite(gzfile, &BVIT(bv,s), (GZ_IO_SIZE_T)cx));
|
||||
} else {
|
||||
FD_EINTR_GUARD(i >= 0 || Sboolean_value(KEYBOARDINTERRUPTPENDING(tc)),
|
||||
flag, i = WRITE(fd, &BVIT(bv,s), (IO_SIZE_T)cx));
|
||||
|
@ -623,7 +601,7 @@ ptr S_put_byte(ptr file, INT byte, IBOOL gzflag) {
|
|||
ptr tc = get_thread_context();
|
||||
INT flag = 0, saved_errno = 0;
|
||||
INT fd = gzflag ? 0 : GET_FD(file);
|
||||
glzFile gzfile = gzflag ? gzxfile_gzfile(file) : NULL;
|
||||
glzFile gzfile = gzflag ? GZXFILE_GZFILE(file) : NULL;
|
||||
octet buf[1];
|
||||
|
||||
buf[0] = (octet)byte;
|
||||
|
@ -634,7 +612,7 @@ ptr S_put_byte(ptr file, INT byte, IBOOL gzflag) {
|
|||
GZ_EINTR_GUARD(
|
||||
i < 0, i > 0 || Sboolean_value(KEYBOARDINTERRUPTPENDING(tc)),
|
||||
flag, gzfile,
|
||||
i = glzwrite(gzfile, buf, 1));
|
||||
i = S_glzwrite(gzfile, buf, 1));
|
||||
} else {
|
||||
FD_EINTR_GUARD(i >= 0 || Sboolean_value(KEYBOARDINTERRUPTPENDING(tc)),
|
||||
flag, i = WRITE(fd, buf, 1));
|
||||
|
@ -664,7 +642,7 @@ ptr S_put_byte(ptr file, INT byte, IBOOL gzflag) {
|
|||
ptr S_get_fd_pos(ptr file, IBOOL gzflag) {
|
||||
errno = 0;
|
||||
if (gzflag) {
|
||||
z_off_t offset = glzseek(gzxfile_gzfile(file), 0, SEEK_CUR);
|
||||
z_off_t offset = S_glzseek(GZXFILE_GZFILE(file), 0, SEEK_CUR);
|
||||
if (offset != -1) return Sinteger64(offset);
|
||||
} else {
|
||||
OFF_T offset = LSEEK(GET_FD(file), 0, SEEK_CUR);
|
||||
|
@ -683,7 +661,7 @@ ptr S_set_fd_pos(ptr file, ptr pos, IBOOL gzflag) {
|
|||
if (sizeof(z_off_t) != sizeof(I64))
|
||||
if (offset != offset64) return Sstring("invalid position");
|
||||
errno = 0;
|
||||
if (glzseek(gzxfile_gzfile(file),offset,SEEK_SET) == offset) return Strue;
|
||||
if (S_glzseek(GZXFILE_GZFILE(file),offset,SEEK_SET) == offset) return Strue;
|
||||
if (errno == 0) return Sstring("compression failed");
|
||||
return S_strerror(errno);
|
||||
} else {
|
||||
|
@ -811,96 +789,115 @@ static int is_valid_lz4_length(iptr len) {
|
|||
/* Accept `iptr` because we expect it to represent a bytevector size,
|
||||
which always fits in `iptr`. Return `uptr`, because the result might
|
||||
not fit in `iptr`. */
|
||||
uptr S_bytevector_compress_size(iptr s_count, IBOOL as_gz) {
|
||||
if (as_gz) {
|
||||
if (is_valid_zlib_length(s_count))
|
||||
return compressBound((uLong)s_count);
|
||||
else {
|
||||
/* Compression will report "source too long" */
|
||||
uptr S_bytevector_compress_size(iptr s_count, INT compress_format) {
|
||||
switch (compress_format) {
|
||||
case COMPRESS_GZIP:
|
||||
if (is_valid_zlib_length(s_count))
|
||||
return compressBound((uLong)s_count);
|
||||
else {
|
||||
/* Compression will report "source too long" */
|
||||
return 0;
|
||||
}
|
||||
case COMPRESS_LZ4:
|
||||
if (is_valid_lz4_length(s_count))
|
||||
return LZ4_compressBound((uLong)s_count);
|
||||
else {
|
||||
/* Compression will report "source too long" */
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
S_error1("S_bytevector_compress_size", "unexpected compress format ~s", FIX(compress_format));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (is_valid_lz4_length(s_count))
|
||||
return LZ4_compressBound((uLong)s_count);
|
||||
else {
|
||||
/* Compression will report "source too long" */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ptr S_bytevector_compress(ptr dest_bv, iptr d_start, iptr d_count,
|
||||
ptr src_bv, iptr s_start, iptr s_count,
|
||||
IBOOL as_gz) {
|
||||
INT compress_format) {
|
||||
/* On error, an message-template string with ~s for the bytevector */
|
||||
if (as_gz) {
|
||||
int r;
|
||||
uLong destLen;
|
||||
|
||||
if (!is_valid_zlib_length(s_count))
|
||||
return Sstring("source bytevector ~s is too large");
|
||||
|
||||
destLen = (uLong)d_count;
|
||||
|
||||
r = compress(&BVIT(dest_bv, d_start), &destLen, &BVIT(src_bv, s_start), (uLong)s_count);
|
||||
|
||||
if (r == Z_OK)
|
||||
return FIX(destLen);
|
||||
else if (r == Z_BUF_ERROR)
|
||||
return Sstring("destination bytevector is too small for compressed form of ~s");
|
||||
else
|
||||
return Sstring("internal error compressing ~s");
|
||||
} else {
|
||||
int destLen;
|
||||
switch (compress_format) {
|
||||
case COMPRESS_GZIP:
|
||||
{
|
||||
int r;
|
||||
uLong destLen;
|
||||
|
||||
if (!is_valid_lz4_length(s_count))
|
||||
return Sstring("source bytevector ~s is too large");
|
||||
if (!is_valid_zlib_length(s_count))
|
||||
return Sstring("source bytevector ~s is too large");
|
||||
|
||||
destLen = (int)d_count;
|
||||
destLen = (uLong)d_count;
|
||||
|
||||
destLen = LZ4_compress_default((char *)&BVIT(src_bv, s_start), (char *)&BVIT(dest_bv, d_start), (int)s_count, (int)d_count);
|
||||
r = compress(&BVIT(dest_bv, d_start), &destLen, &BVIT(src_bv, s_start), (uLong)s_count);
|
||||
|
||||
if (destLen > 0)
|
||||
return Sfixnum(destLen);
|
||||
else
|
||||
return Sstring("compression failed for ~s");
|
||||
if (r == Z_OK)
|
||||
return FIX(destLen);
|
||||
else if (r == Z_BUF_ERROR)
|
||||
return Sstring("destination bytevector is too small for compressed form of ~s");
|
||||
else
|
||||
return Sstring("internal error compressing ~s");
|
||||
}
|
||||
case COMPRESS_LZ4:
|
||||
{
|
||||
int destLen;
|
||||
|
||||
if (!is_valid_lz4_length(s_count))
|
||||
return Sstring("source bytevector ~s is too large");
|
||||
|
||||
destLen = (int)d_count;
|
||||
|
||||
destLen = LZ4_compress_default((char *)&BVIT(src_bv, s_start), (char *)&BVIT(dest_bv, d_start), (int)s_count, (int)d_count);
|
||||
|
||||
if (destLen > 0)
|
||||
return Sfixnum(destLen);
|
||||
else
|
||||
return Sstring("compression failed for ~s");
|
||||
}
|
||||
default:
|
||||
S_error1("S_bytevector_compress", "unexpected compress format ~s", FIX(compress_format));
|
||||
return Sfalse;
|
||||
}
|
||||
}
|
||||
|
||||
ptr S_bytevector_uncompress(ptr dest_bv, iptr d_start, iptr d_count,
|
||||
ptr src_bv, iptr s_start, iptr s_count,
|
||||
IBOOL as_gz) {
|
||||
INT compress_format) {
|
||||
/* On error, an message-template string with ~s for the bytevector */
|
||||
if (as_gz) {
|
||||
int r;
|
||||
uLongf destLen;
|
||||
switch (compress_format) {
|
||||
case COMPRESS_GZIP:
|
||||
{
|
||||
int r;
|
||||
uLongf destLen;
|
||||
|
||||
if (!is_valid_zlib_length(d_count))
|
||||
return Sstring("expected result size of uncompressed source ~s is too large");
|
||||
if (!is_valid_zlib_length(d_count))
|
||||
return Sstring("expected result size of uncompressed source ~s is too large");
|
||||
|
||||
destLen = (uLongf)d_count;
|
||||
destLen = (uLongf)d_count;
|
||||
|
||||
r = uncompress(&BVIT(dest_bv, d_start), &destLen, &BVIT(src_bv, s_start), (uLong)s_count);
|
||||
r = uncompress(&BVIT(dest_bv, d_start), &destLen, &BVIT(src_bv, s_start), (uLong)s_count);
|
||||
|
||||
if (r == Z_OK)
|
||||
return FIX(destLen);
|
||||
else if (r == Z_BUF_ERROR)
|
||||
return Sstring("uncompressed ~s is larger than expected size");
|
||||
else if (r == Z_DATA_ERROR)
|
||||
return Sstring("invalid data in source bytevector ~s");
|
||||
else
|
||||
return Sstring("internal error uncompressing ~s");
|
||||
} else {
|
||||
int r;
|
||||
if (r == Z_OK)
|
||||
return FIX(destLen);
|
||||
else if (r == Z_BUF_ERROR)
|
||||
return Sstring("uncompressed ~s is larger than expected size");
|
||||
else if (r == Z_DATA_ERROR)
|
||||
return Sstring("invalid data in source bytevector ~s");
|
||||
else
|
||||
return Sstring("internal error uncompressing ~s");
|
||||
}
|
||||
case COMPRESS_LZ4:
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!is_valid_lz4_length(d_count))
|
||||
return Sstring("expected result size of uncompressed source ~s is too large");
|
||||
if (!is_valid_lz4_length(d_count))
|
||||
return Sstring("expected result size of uncompressed source ~s is too large");
|
||||
|
||||
r = LZ4_decompress_safe((char *)&BVIT(src_bv, s_start), (char *)&BVIT(dest_bv, d_start), (int)s_count, (int)d_count);
|
||||
r = LZ4_decompress_safe((char *)&BVIT(src_bv, s_start), (char *)&BVIT(dest_bv, d_start), (int)s_count, (int)d_count);
|
||||
|
||||
if (r >= 0)
|
||||
return Sfixnum(r);
|
||||
else
|
||||
return Sstring("internal error uncompressing ~s");
|
||||
if (r >= 0)
|
||||
return Sfixnum(r);
|
||||
else
|
||||
return Sstring("internal error uncompressing ~s");
|
||||
}
|
||||
default:
|
||||
return Sstring("unepxected compress format ~s");
|
||||
}
|
||||
}
|
||||
|
|
10
c/number.c
10
c/number.c
|
@ -637,9 +637,13 @@ static ptr big_mul(tc, x, y, xl, yl, sign) ptr tc, x, y; iptr xl, yl; IBOOL sign
|
|||
return copy_normalize(&BIGIT(W(tc),0),xl+yl,sign);
|
||||
}
|
||||
|
||||
#define SHORTMIN ((most_negative_fixnum / (1 << (fixnum_bits / 2))) + 1)
|
||||
#define SHORTMAX (most_positive_fixnum / (1 << (fixnum_bits / 2)))
|
||||
#define SHORTRANGE(x) ((x) >= SHORTMIN && (x) <= SHORTMAX)
|
||||
/* SHORTRANGE is -floor(sqrt(most_positive_fixnum))..floor(sqrt(most_positive_fixnum)).
|
||||
We don't use sqrt because it rounds up for fixnum_bits = 61 */
|
||||
#if (fixnum_bits == 30)
|
||||
#define SHORTRANGE(x) (-23170 <= (x) && (x) <= 23170)
|
||||
#elif (fixnum_bits == 61)
|
||||
#define SHORTRANGE(x) (-0x3FFFFFFF <= (x) && (x) <= 0x3FFFFFFF)
|
||||
#endif
|
||||
|
||||
ptr S_mul(x, y) ptr x, y; {
|
||||
ptr tc = get_thread_context();
|
||||
|
|
106
c/scheme.c
106
c/scheme.c
|
@ -589,17 +589,17 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
path = name;
|
||||
|
||||
if (fd != -1) {
|
||||
file = glzdopen(fd, "rb");
|
||||
file = S_glzdopen_input(fd);
|
||||
} else {
|
||||
#ifdef WIN32
|
||||
expandedpath = S_malloc_wide_pathname(path);
|
||||
file = glzopen_w(expandedpath, "rb");
|
||||
file = S_glzopen_input_w(expandedpath);
|
||||
#else
|
||||
expandedpath = S_malloc_pathname(path);
|
||||
file = glzopen(expandedpath, "rb");
|
||||
file = S_glzopen_input(expandedpath);
|
||||
#endif
|
||||
/* assumption (seemingly true based on a glance at the source code):
|
||||
glzopen doesn't squirrel away a pointer to expandedpath. */
|
||||
S_glzopen_input doesn't squirrel away a pointer to expandedpath. */
|
||||
free(expandedpath);
|
||||
}
|
||||
|
||||
|
@ -615,14 +615,14 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
if (verbose) fprintf(stderr, "trying %s...opened\n", path);
|
||||
|
||||
/* check for magic number */
|
||||
if (glzgetc(file) != fasl_type_header ||
|
||||
glzgetc(file) != 0 ||
|
||||
glzgetc(file) != 0 ||
|
||||
glzgetc(file) != 0 ||
|
||||
glzgetc(file) != 'c' ||
|
||||
glzgetc(file) != 'h' ||
|
||||
glzgetc(file) != 'e' ||
|
||||
glzgetc(file) != 'z') {
|
||||
if (S_glzgetc(file) != fasl_type_header ||
|
||||
S_glzgetc(file) != 0 ||
|
||||
S_glzgetc(file) != 0 ||
|
||||
S_glzgetc(file) != 0 ||
|
||||
S_glzgetc(file) != 'c' ||
|
||||
S_glzgetc(file) != 'h' ||
|
||||
S_glzgetc(file) != 'e' ||
|
||||
S_glzgetc(file) != 'z') {
|
||||
fprintf(stderr, "malformed fasl-object header in %s\n", path);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
|
@ -630,7 +630,7 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
/* check version */
|
||||
if (zget_uptr(file, &n) != 0) {
|
||||
fprintf(stderr, "unexpected end of file on %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
|
||||
|
@ -638,21 +638,21 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
fprintf(stderr, "%s is for Version %s; ", path, S_format_scheme_version(n));
|
||||
/* use separate fprintf since S_format_scheme_version returns static string */
|
||||
fprintf(stderr, "need Version %s\n", S_format_scheme_version(scheme_version));
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
|
||||
/* check machine type */
|
||||
if (zget_uptr(file, &n) != 0) {
|
||||
fprintf(stderr, "unexpected end of file on %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
|
||||
if (n != machine_type) {
|
||||
fprintf(stderr, "%s is for machine-type %s; need machine-type %s\n", path,
|
||||
S_lookup_machine_type(n), S_lookup_machine_type(machine_type));
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
} else {
|
||||
|
@ -675,13 +675,13 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
|
||||
#ifdef WIN32
|
||||
expandedpath = S_malloc_wide_pathname(path);
|
||||
file = glzopen_w(expandedpath, "rb");
|
||||
file = S_glzopen_input_w(expandedpath);
|
||||
#else
|
||||
expandedpath = S_malloc_pathname(path);
|
||||
file = glzopen(expandedpath, "rb");
|
||||
file = S_glzopen_input(expandedpath);
|
||||
#endif
|
||||
/* assumption (seemingly true based on a glance at the source code):
|
||||
glzopen doesn't squirrel away a pointer to expandedpath. */
|
||||
S_glzopen_input doesn't squirrel away a pointer to expandedpath. */
|
||||
free(expandedpath);
|
||||
if (!file) {
|
||||
if (verbose) fprintf(stderr, "trying %s...cannot open\n", path);
|
||||
|
@ -691,23 +691,23 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
if (verbose) fprintf(stderr, "trying %s...opened\n", path);
|
||||
|
||||
/* check for magic number */
|
||||
if (glzgetc(file) != fasl_type_header ||
|
||||
glzgetc(file) != 0 ||
|
||||
glzgetc(file) != 0 ||
|
||||
glzgetc(file) != 0 ||
|
||||
glzgetc(file) != 'c' ||
|
||||
glzgetc(file) != 'h' ||
|
||||
glzgetc(file) != 'e' ||
|
||||
glzgetc(file) != 'z') {
|
||||
if (S_glzgetc(file) != fasl_type_header ||
|
||||
S_glzgetc(file) != 0 ||
|
||||
S_glzgetc(file) != 0 ||
|
||||
S_glzgetc(file) != 0 ||
|
||||
S_glzgetc(file) != 'c' ||
|
||||
S_glzgetc(file) != 'h' ||
|
||||
S_glzgetc(file) != 'e' ||
|
||||
S_glzgetc(file) != 'z') {
|
||||
if (verbose) fprintf(stderr, "malformed fasl-object header in %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check version */
|
||||
if (zget_uptr(file, &n) != 0) {
|
||||
if (verbose) fprintf(stderr, "unexpected end of file on %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -717,14 +717,14 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
/* use separate fprintf since S_format_scheme_version returns static string */
|
||||
fprintf(stderr, "need Version %s\n", S_format_scheme_version(scheme_version));
|
||||
}
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check machine type */
|
||||
if (zget_uptr(file, &n) != 0) {
|
||||
if (verbose) fprintf(stderr, "unexpected end of file on %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -732,7 +732,7 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
if (verbose)
|
||||
fprintf(stderr, "%s is for machine-type %s; need machine-type %s\n", path,
|
||||
S_lookup_machine_type(n), S_lookup_machine_type(machine_type));
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -742,56 +742,56 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
|
||||
if (verbose) fprintf(stderr, "version and machine type check\n");
|
||||
|
||||
if (glzgetc(file) != '(') { /* ) */
|
||||
if (S_glzgetc(file) != '(') { /* ) */
|
||||
fprintf(stderr, "malformed boot file %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
|
||||
/* ( */
|
||||
if ((c = glzgetc(file)) == ')') {
|
||||
if ((c = S_glzgetc(file)) == ')') {
|
||||
if (boot_count != 0) {
|
||||
fprintf(stderr, "base boot file %s must come before other boot files\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
} else {
|
||||
if (boot_count == 0) {
|
||||
for (;;) {
|
||||
glzungetc(c, file);
|
||||
S_glzungetc(c, file);
|
||||
/* try to load heap or boot file this boot file requires */
|
||||
if (zgetstr(file, buf, PATH_MAX) != 0) {
|
||||
fprintf(stderr, "unexpected end of file on %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
if (find_boot(buf, ".boot", -1, 0)) break;
|
||||
if ((c = glzgetc(file)) == ')') {
|
||||
if ((c = S_glzgetc(file)) == ')') {
|
||||
char *sep; char *wastebuf[8];
|
||||
fprintf(stderr, "cannot find subordinate boot file ");
|
||||
glzrewind(file);
|
||||
(void) glzread(file, wastebuf, 8); /* magic number */
|
||||
S_glzrewind(file);
|
||||
(void) S_glzread(file, wastebuf, 8); /* magic number */
|
||||
(void) zget_uptr(file, &n); /* version */
|
||||
(void) zget_uptr(file, &n); /* machine type */
|
||||
(void) glzgetc(file); /* open paren */
|
||||
(void) S_glzgetc(file); /* open paren */
|
||||
for (sep = ""; ; sep = "or ") {
|
||||
if ((c = glzgetc(file)) == ')') break;
|
||||
glzungetc(c, file);
|
||||
if ((c = S_glzgetc(file)) == ')') break;
|
||||
S_glzungetc(c, file);
|
||||
(void) zgetstr(file, buf, PATH_MAX);
|
||||
fprintf(stderr, "%s%s.boot ", sep, buf);
|
||||
}
|
||||
fprintf(stderr, "required by %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* skip to end of header */
|
||||
while ((c = glzgetc(file)) != ')') {
|
||||
while ((c = S_glzgetc(file)) != ')') {
|
||||
if (c < 0) {
|
||||
fprintf(stderr, "malformed boot file %s\n", path);
|
||||
glzclose(file);
|
||||
S_glzclose(file);
|
||||
S_abnormal_exit();
|
||||
}
|
||||
}
|
||||
|
@ -812,11 +812,11 @@ static IBOOL find_boot(name, ext, fd, errorp) const char *name, *ext; int fd; IB
|
|||
static uptr zget_uptr(glzFile file, uptr *pn) {
|
||||
uptr n, m; int c; octet k;
|
||||
|
||||
if ((c = glzgetc(file)) < 0) return -1;
|
||||
if ((c = S_glzgetc(file)) < 0) return -1;
|
||||
k = (octet)c;
|
||||
n = k >> 1;
|
||||
while (k & 1) {
|
||||
if ((c = glzgetc(file)) < 0) return -1;
|
||||
if ((c = S_glzgetc(file)) < 0) return -1;
|
||||
k = (octet)c;
|
||||
m = n << 7;
|
||||
if (m >> 7 != n) return -1;
|
||||
|
@ -830,9 +830,9 @@ static INT zgetstr(file, s, max) glzFile file; char *s; iptr max; {
|
|||
ICHAR c;
|
||||
|
||||
while (max-- > 0) {
|
||||
if ((c = glzgetc(file)) < 0) return -1;
|
||||
if ((c = S_glzgetc(file)) < 0) return -1;
|
||||
if (c == ' ' || c == ')') {
|
||||
if (c == ')') glzungetc(c, file);
|
||||
if (c == ')') S_glzungetc(c, file);
|
||||
*s = 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -927,7 +927,7 @@ static void load(tc, n, base) ptr tc; iptr n; IBOOL base; {
|
|||
}
|
||||
|
||||
S_G.load_binary = Sfalse;
|
||||
glzclose(bd[n].file);
|
||||
S_glzclose(bd[n].file);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -1144,6 +1144,8 @@ extern void Sbuild_heap(kernel, custom_init) const char *kernel; void (*custom_i
|
|||
/* #scheme-init enables interrupts */
|
||||
TRAP(tc) = (ptr)most_positive_fixnum;
|
||||
DISABLECOUNT(tc) = Sfixnum(1);
|
||||
COMPRESSFORMAT(tc) = FIX(COMPRESS_LZ4);
|
||||
COMPRESSLEVEL(tc) = FIX(COMPRESS_MEDIUM);
|
||||
|
||||
load(tc, i++, 1);
|
||||
S_boot_time = 0;
|
||||
|
|
|
@ -28,13 +28,14 @@
|
|||
|
||||
#include "version.h"
|
||||
#include <stdio.h>
|
||||
#include "compress-io.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include "compress-io.h"
|
||||
|
||||
#ifndef EXTERN
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
|
|
@ -122,6 +122,8 @@ ptr S_create_thread_object(who, p_tc) const char *who; ptr p_tc; {
|
|||
|
||||
GUARDIANENTRIES(tc) = Snil;
|
||||
|
||||
LZ4OUTBUFFER(tc) = NULL;
|
||||
|
||||
tc_mutex_release()
|
||||
|
||||
return thread;
|
||||
|
@ -225,7 +227,9 @@ static IBOOL destroy_thread(tc) ptr tc; {
|
|||
}
|
||||
}
|
||||
|
||||
free((void *)THREADTC(thread));
|
||||
if (LZ4OUTBUFFER(tc) != NULL) free(LZ4OUTBUFFER(tc));
|
||||
|
||||
free((void *)tc);
|
||||
THREADTC(thread) = 0; /* mark it dead */
|
||||
status = 1;
|
||||
break;
|
||||
|
|
2
checkin
2
checkin
|
@ -294,7 +294,7 @@ endif
|
|||
|
||||
delete:
|
||||
|
||||
set tmpfiles = `(cd $W; find . -name zlib -prune -o -type f -print)`
|
||||
set tmpfiles = `(cd $W; find . -name zlib -prune -o -name lz4 -prune -o -type f -print)`
|
||||
set files = ()
|
||||
foreach x ($tmpfiles)
|
||||
set files = ($x $files)
|
||||
|
|
|
@ -93,7 +93,7 @@ be reordered to put those that are most frequently executed first.
|
|||
[i 1]
|
||||
[ii 2]
|
||||
[iii 3]
|
||||
[(iiii iv) 3]
|
||||
[(iiii iv) 4]
|
||||
[else 'out-of-range])) ;=> 2
|
||||
|
||||
(define p
|
||||
|
|
48
csug/io.stex
48
csug/io.stex
|
@ -208,8 +208,10 @@ Section~\ref{TSPL:SECTOPENINGFILES} of {\TSPLFOUR}.
|
|||
\item[\var{compressed}:]
|
||||
An output file should be compressed when written; and a compressed input
|
||||
file should be decompressed when read. The compression format for output
|
||||
is determined by the \scheme{compress-format} parameter, while the compression
|
||||
format on input is inferred.
|
||||
is determined by the \index{\scheme{compress-format}}\scheme{compress-format}
|
||||
parameter, while the compression format on input is inferred.
|
||||
The compression level, which is relevant only for output, is determined
|
||||
by the \index{\scheme{compress-level}}\scheme{compress-level} parameter.
|
||||
|
||||
\item[\var{replace}:]
|
||||
For output files only, replace (remove and recreate) the existing file if
|
||||
|
@ -975,8 +977,10 @@ will be compressed.
|
|||
If the port is an input port, subsequent input will be decompressed
|
||||
if and only if the port is currently pointing at compressed data.
|
||||
The compression format for output
|
||||
is determined by the \scheme{compress-format} parameter, while the compression
|
||||
format on input is inferred.
|
||||
is determined by the \index{\scheme{compress-format}}\scheme{compress-format}
|
||||
parameter, while the compression format on input is inferred.
|
||||
The compression level, which is relevant only for output, is determined
|
||||
by the \index{\scheme{compress-level}}\scheme{compress-level} parameter.
|
||||
This procedure has no effect if the port is already set for compression.
|
||||
|
||||
%----------------------------------------------------------------------------
|
||||
|
@ -986,23 +990,41 @@ This procedure has no effect if the port is already set for compression.
|
|||
\endnoskipentryheader
|
||||
|
||||
\noindent
|
||||
\scheme{compress-format} is a parameter that determines the
|
||||
compression algorithm and format that is used for output. Currently,
|
||||
the possible values of the parameter are \scheme{'lz4} (the default)
|
||||
and \scheme{'gzip}.
|
||||
\scheme{compress-format} determines the
|
||||
compression algorithm and format used for output. Currently,
|
||||
the possible values of the parameter are the symbols \scheme{lz4} (the default)
|
||||
and \scheme{gzip}.
|
||||
|
||||
The \scheme{'lz4} format uses the LZ4 compression library developed by
|
||||
The \scheme{lz4} format uses the LZ4 compression library developed by
|
||||
Yann Collet.
|
||||
It is therefore compatible with the \scheme{lz4} program, which
|
||||
means that \scheme{lz4} may be used to uncompress files produced
|
||||
by {\ChezScheme} and visa versa.
|
||||
|
||||
The \scheme{'gzip} format uses the zlib compression library developed by
|
||||
The \scheme{gzip} format uses the zlib compression library developed by
|
||||
Jean-loup Gailly and Mark Adler.
|
||||
It is therefore compatible with the \scheme{gzip} program, which
|
||||
means that \scheme{gzip} may be used to uncompress files produced
|
||||
by {\ChezScheme} and visa versa.
|
||||
|
||||
Reading \scheme{lz4}-compressed data tends to be much faster than reading
|
||||
\scheme{gzip}-compressed data, while \scheme{gzip}-compressed data tends to
|
||||
be significantly smaller.
|
||||
|
||||
%----------------------------------------------------------------------------
|
||||
\entryheader
|
||||
\formdef{compress-level}{\categorythreadparameter}{compress-level}
|
||||
\listlibraries
|
||||
\endnoskipentryheader
|
||||
|
||||
\noindent
|
||||
\scheme{compress-level} determines the amount of effort spent on
|
||||
compression and is thus relevant only for output.
|
||||
It can be set to one of the symbols \scheme{low},
|
||||
\scheme{medium}, \scheme{high}, or \scheme{maximum}, which are
|
||||
listed in order from shortest to longest expected compression time
|
||||
and least to greatest expected effectiveness.
|
||||
Its default value is \scheme{medium}.
|
||||
|
||||
\section{String Ports\label{SECTIOSTRINGPORTS}}
|
||||
|
||||
|
@ -1858,7 +1880,11 @@ The default behavior is to raise an exception.
|
|||
The mutually exclusive \scheme{compressed} and
|
||||
\scheme{uncompressed} options determine whether the output file is to
|
||||
be compressed.
|
||||
The compression format is determined by the \scheme{compress-format} parameter.
|
||||
The compression format and level are determined by the
|
||||
\index{\scheme{compress-format}}\scheme{compress-format}
|
||||
and
|
||||
\index{\scheme{compress-level}}\scheme{compress-level}
|
||||
parameters.
|
||||
Files are uncompressed by default, so the \scheme{uncompressed}
|
||||
option is useful only as documentation.
|
||||
|
||||
|
|
|
@ -1179,7 +1179,12 @@ The result is the raw compressed data with a minimal header to record
|
|||
the uncompressed size and the compression mode. The result does not include
|
||||
the header that is written by port-based compression using the
|
||||
\scheme{compressed} option. The compression format is determined by the
|
||||
\scheme{compress-format} parameter.
|
||||
\index{\scheme{compress-format}}\scheme{compress-format}
|
||||
parameter.
|
||||
The compression level is fixed to some default determined by the
|
||||
format; it is not affected by the
|
||||
\index{\scheme{compress-level}}\scheme{compress-level}
|
||||
parameter.
|
||||
|
||||
|
||||
%----------------------------------------------------------------------------
|
||||
|
|
|
@ -2627,6 +2627,11 @@ When this parameter is \scheme{#t}, the default, \scheme{compile-file},
|
|||
\scheme{compile-program}, \scheme{compile-to-file},
|
||||
\scheme{compile-whole-program}, and \scheme{strip-fasl-file} compress
|
||||
the object files they create.
|
||||
The compression format and level are determined by the
|
||||
\index{\scheme{compress-format}}\scheme{compress-format}
|
||||
and
|
||||
\index{\scheme{compress-level}}\scheme{compress-level}
|
||||
parameters.
|
||||
|
||||
|
||||
%----------------------------------------------------------------------------
|
||||
|
|
|
@ -216,6 +216,16 @@ continuation invocation, the mutex is reacquired.
|
|||
Using \scheme{with-mutex} is generally more convenient and safer than using
|
||||
\scheme{mutex-acquire} and \scheme{mutex-release} directly.
|
||||
|
||||
%----------------------------------------------------------------------------
|
||||
\entryheader
|
||||
\formdef{mutex-name}{\categoryprocedure}{(mutex-name \var{mutex})}
|
||||
\returns the name associated with \var{mutex}, if any; otherwise \scheme{#f}
|
||||
\listlibraries
|
||||
\endentryheader
|
||||
|
||||
\noindent
|
||||
\var{mutex} must be a mutex.
|
||||
|
||||
\section{Conditions}
|
||||
|
||||
%----------------------------------------------------------------------------
|
||||
|
@ -292,6 +302,16 @@ condition identified by \var{cond}.
|
|||
\scheme{condition-broadcast} releases all of the threads waiting for the
|
||||
condition identified by \var{cond}.
|
||||
|
||||
%----------------------------------------------------------------------------
|
||||
\entryheader
|
||||
\formdef{condition-name}{\categoryprocedure}{(condition-name \var{condition})}
|
||||
\returns the name associated with \var{condition}, if any; otherwise \scheme{#f}
|
||||
\listlibraries
|
||||
\endentryheader
|
||||
|
||||
\noindent
|
||||
\var{condition} must be a condition.
|
||||
|
||||
\section{Locks\label{SECTTHREADLOCKS}}
|
||||
|
||||
\index{locks}%
|
||||
|
|
|
@ -241,7 +241,6 @@
|
|||
#(index-entry "./records.html#./records:s22" ("rtd") ("rtd") "331" "" "")
|
||||
#(index-entry "./records.html#./records:s21" ("record-type descriptor") ("record-type descriptor") "331" "" "")
|
||||
#(index-entry "./records.html#./records:s20" ("make-record-type-descriptor") ("\\scheme{make-record-type-descriptor}") "331" "emph" "")
|
||||
#(index-entry "./records.html#./records:s19" ("make-record-type-descriptor") ("make-record-type-descriptor") "331" "" "")
|
||||
#(index-entry "./records.html#./records:s18" ("rtd") ("rtd") "331" "" "")
|
||||
#(index-entry "./records.html#./records:s17" ("record-type descriptor") ("record-type descriptor") "331" "" "")
|
||||
#(index-entry "./records.html#./records:s16" ("parent-rtd") ("\\scheme{parent-rtd}") "331" "emph" "")
|
||||
|
|
|
@ -1171,7 +1171,6 @@
|
|||
\indexentry{parent-rtd@\scheme{parent-rtd}|emph}{331}
|
||||
\indexentry{record-type descriptor}{331}
|
||||
\indexentry{rtd}{331}
|
||||
\indexentry{make-record-type-descriptor}{331}
|
||||
\indexentry{make-record-type-descriptor@\scheme{make-record-type-descriptor}|emph}{331}
|
||||
\indexentry{record-type descriptor}{331}
|
||||
\indexentry{rtd}{331}
|
||||
|
|
91
mats/5_2.ms
91
mats/5_2.ms
|
@ -165,6 +165,97 @@
|
|||
(mat length
|
||||
(= (length '(1 2 3 4 5)) 5)
|
||||
(= (length '()) 0)
|
||||
; check that expand-primitives doesn't generate incorrect code.
|
||||
; we don't check that it optimizes, however.
|
||||
(let ([ls* (map make-list '(0 1 2 3 4 5 8 9 10 99 100 101 1000))])
|
||||
(define-syntax test1
|
||||
(syntax-rules ()
|
||||
[(_ prim)
|
||||
(let ()
|
||||
(define (f x)
|
||||
(and
|
||||
(prim (#3%length x))
|
||||
(prim (#3%length x))))
|
||||
(andmap
|
||||
(lambda (x)
|
||||
(let ([n (length x)])
|
||||
(equal?
|
||||
(f x)
|
||||
(prim n))))
|
||||
ls*))]))
|
||||
(define-syntax test2
|
||||
(syntax-rules ()
|
||||
[(_ prim)
|
||||
(let ()
|
||||
(define (f x)
|
||||
(and
|
||||
(prim (#3%length x) 0)
|
||||
(prim 0 (#3%length x))
|
||||
(prim (#3%length x) 1)
|
||||
(prim 1 (#3%length x))
|
||||
(prim (#3%length x) 4)
|
||||
(prim 4 (#3%length x))
|
||||
(prim (#3%length x) 9)
|
||||
(prim 9 (#3%length x))
|
||||
(prim (#3%length x) 100)
|
||||
(prim 100 (#3%length x))))
|
||||
(andmap
|
||||
(lambda (x)
|
||||
(let ([n (length x)])
|
||||
(equal?
|
||||
(f x)
|
||||
(and
|
||||
(prim n 0)
|
||||
(prim 0 n)
|
||||
(prim n 1)
|
||||
(prim 1 n)
|
||||
(prim n 4)
|
||||
(prim 4 n)
|
||||
(prim n 9)
|
||||
(prim 9 n)
|
||||
(prim n 100)
|
||||
(prim 100 n)))))
|
||||
ls*))]))
|
||||
(and
|
||||
(test1 zero?)
|
||||
(test1 positive?)
|
||||
(test1 nonnegative?)
|
||||
(test1 negative?)
|
||||
(test1 nonpositive?)
|
||||
(test1 fxzero?)
|
||||
(test1 fxpositive?)
|
||||
(test1 fxnonnegative?)
|
||||
(test1 fxnegative?)
|
||||
(test1 fxnonpositive?)
|
||||
(test2 eq?)
|
||||
(test2 eqv?)
|
||||
(test2 equal?)
|
||||
(test2 <)
|
||||
(test2 <=)
|
||||
(test2 =)
|
||||
(test2 >=)
|
||||
(test2 >)
|
||||
(test2 r6rs:<)
|
||||
(test2 r6rs:<=)
|
||||
(test2 r6rs:=)
|
||||
(test2 r6rs:>=)
|
||||
(test2 r6rs:>)
|
||||
(test2 r6rs:<)
|
||||
(test2 r6rs:<=)
|
||||
(test2 r6rs:=)
|
||||
(test2 r6rs:>=)
|
||||
(test2 r6rs:>)
|
||||
(test2 fx<)
|
||||
(test2 fx<=)
|
||||
(test2 fx=)
|
||||
(test2 fx>=)
|
||||
(test2 fx>)
|
||||
(test2 fx<?)
|
||||
(test2 fx<=?)
|
||||
(test2 fx=?)
|
||||
(test2 fx>=?)
|
||||
(test2 fx>?)
|
||||
(test2 #%$fxu<)))
|
||||
)
|
||||
|
||||
(mat list-ref
|
||||
|
|
32
mats/5_3.ms
32
mats/5_3.ms
|
@ -1628,14 +1628,30 @@
|
|||
(error? (* 'a 3 4))
|
||||
(error? (* 3 5 'a 4))
|
||||
(eqv? (* 1 2) 2)
|
||||
(let loop ([n 0])
|
||||
(or (= n 100)
|
||||
(and
|
||||
(eqv? (* (expt 2 n) (expt 2 n)) (expt 2 (* 2 n)))
|
||||
(eqv? (* (- (expt 2 n)) (- (expt 2 n))) (expt 2 (* 2 n)))
|
||||
(eqv? (* (- (expt 2 n)) (expt 2 n)) (- (expt 2 (* 2 n))))
|
||||
(eqv? (* (expt 2 n) (- (expt 2 n))) (- (expt 2 (* 2 n))))
|
||||
(loop (add1 n)))))
|
||||
(eqv? (* 23170 23170) 536848900)
|
||||
(eqv? (* 23170 -23170) -536848900)
|
||||
(eqv? (* -23170 23170) -536848900)
|
||||
(eqv? (* -23170 -23170) 536848900)
|
||||
(eqv? (* 23171 23170) 536872070)
|
||||
(eqv? (* 23171 -23170) -536872070)
|
||||
(eqv? (* -23171 23170) -536872070)
|
||||
(eqv? (* -23171 -23170) 536872070)
|
||||
(eqv? (* 23171 23171) 536895241)
|
||||
(eqv? (* 23171 -23171) -536895241)
|
||||
(eqv? (* -23171 23171) -536895241)
|
||||
(eqv? (* -23171 -23171) 536895241)
|
||||
(eqv? (* #x3FFFFFFF #x3FFFFFFF) #xFFFFFFF80000001)
|
||||
(eqv? (* #x3FFFFFFF #x-3FFFFFFF) #x-FFFFFFF80000001)
|
||||
(eqv? (* #x-3FFFFFFF #x3FFFFFFF) #x-FFFFFFF80000001)
|
||||
(eqv? (* #x-3FFFFFFF #x-3FFFFFFF) #xFFFFFFF80000001)
|
||||
(eqv? (* #x40000000 #x3FFFFFFF) #xFFFFFFFC0000000)
|
||||
(eqv? (* #x40000000 #x-3FFFFFFF) #x-FFFFFFFC0000000)
|
||||
(eqv? (* #x-40000000 #x3FFFFFFF) #x-FFFFFFFC0000000)
|
||||
(eqv? (* #x-40000000 #x-3FFFFFFF) #xFFFFFFFC0000000)
|
||||
(eqv? (* #x40000000 #x40000000) #x1000000000000000)
|
||||
(eqv? (* #x40000000 #x-40000000) #x-1000000000000000)
|
||||
(eqv? (* #x-40000000 #x40000000) #x-1000000000000000)
|
||||
(eqv? (* #x-40000000 #x-40000000) #x1000000000000000)
|
||||
(fl~= (* 1.0 2) 2.0)
|
||||
(fl~= (* 1 2.0) 2.0)
|
||||
(eqv? (* 3/5 2/5) 6/25)
|
||||
|
|
|
@ -11277,7 +11277,7 @@
|
|||
|
||||
|
||||
(mat bytevector-compress
|
||||
(parameters [compress-format 'gzip] [compress-format 'lz4])
|
||||
(parameters [compress-format 'gzip 'lz4])
|
||||
(error? (bytevector-compress 7))
|
||||
(error? (bytevector-compress "hello"))
|
||||
(error? (bytevector-uncompress 7))
|
||||
|
@ -11300,19 +11300,6 @@
|
|||
(error?
|
||||
;; Need at least 8 bytes for result size
|
||||
(bytevector-uncompress '#vu8(0 0 0 0 0 0 255)))
|
||||
(error?
|
||||
;; Fail if the uncompressed result is too big
|
||||
(bytevector-uncompress (let ([bv (bytevector-compress (string->utf8 "hello"))])
|
||||
(bytevector-u64-set! bv 0 (sub1 (bytevector-u64-ref bv 0 (endianness big))) (endianness big))
|
||||
bv)))
|
||||
(error?
|
||||
;; Fail if the uncompressed result is too small
|
||||
(bytevector-uncompress (let ([bv (bytevector-compress (string->utf8 "hello"))])
|
||||
(bytevector-u64-set! bv 0 (add1 (bytevector-u64-ref bv 0 (endianness big))) (endianness big))
|
||||
bv)))
|
||||
(error?
|
||||
;; Compressed data always starts with 0x78, so this one isn't valid:
|
||||
(bytevector-uncompress '#vu8(0 0 0 0 0 0 0 255 1 2 3)))
|
||||
(error?
|
||||
;; Claming a too-large size in the header should fail with a suitable message:
|
||||
(bytevector-uncompress '#vu8(255 255 255 255 255 255 255 255 1 2 3)))
|
||||
|
|
59
mats/io.ms
59
mats/io.ms
|
@ -2126,8 +2126,63 @@
|
|||
(= q (custom-port-buffer-size)))))
|
||||
)
|
||||
|
||||
(mat compress-parameters
|
||||
(error? ; unsupported format
|
||||
(compress-format 'foo))
|
||||
(error? ; unsupported format
|
||||
(compress-format "gzip"))
|
||||
(eq? (compress-format) 'lz4)
|
||||
(eq? (parameterize ([compress-format 'gzip]) (compress-format)) 'gzip)
|
||||
(eq? (parameterize ([compress-format 'lz4]) (compress-format)) 'lz4)
|
||||
(error? ; unsupported level
|
||||
(compress-level 'foo))
|
||||
(error? ; unsupported level
|
||||
(compress-level 1))
|
||||
(eq? (compress-level) 'medium)
|
||||
(eq? (parameterize ([compress-level 'low]) (compress-level)) 'low)
|
||||
(eq? (parameterize ([compress-level 'medium]) (compress-level)) 'medium)
|
||||
(eq? (parameterize ([compress-level 'high]) (compress-level)) 'high)
|
||||
(eq? (parameterize ([compress-level 'maximum]) (compress-level)) 'maximum)
|
||||
(begin
|
||||
(define (fnlength ifn) (call-with-port (open-file-input-port ifn) port-length))
|
||||
(define (compress-file ifn ofn fmt lvl)
|
||||
(call-with-port (open-file-input-port ifn)
|
||||
(lambda (ip)
|
||||
(call-with-port (parameterize ([compress-format fmt] [compress-level lvl])
|
||||
(open-file-output-port ofn (file-options compressed replace)))
|
||||
(lambda (op) (put-bytevector op (get-bytevector-all ip))))))
|
||||
(fnlength ofn))
|
||||
(define (compress-file-test fmt)
|
||||
(let ([orig (fnlength "prettytest.ss")]
|
||||
[low (compress-file "prettytest.ss" "testfile.ss" fmt 'low)]
|
||||
[medium (compress-file "prettytest.ss" "testfile.ss" fmt 'medium)]
|
||||
[high (compress-file "prettytest.ss" "testfile.ss" fmt 'high)]
|
||||
[maximum (compress-file "prettytest.ss" "testfile.ss" fmt 'maximum)])
|
||||
(define-syntax test1
|
||||
(syntax-rules ()
|
||||
[(_ level)
|
||||
(unless (< level orig) (errorf #f "~s ~s did not compress" fmt 'level))]))
|
||||
(define-syntax test2
|
||||
(syntax-rules ()
|
||||
[(_ level1 level2)
|
||||
(unless (<= level2 level1) (errorf #f "~s ~s did worse than ~s" fmt 'level2 'level1))]))
|
||||
(test1 low)
|
||||
(test1 medium)
|
||||
(test1 high)
|
||||
(test1 maximum)
|
||||
(test2 low medium)
|
||||
(test2 medium high)
|
||||
(test2 high maximum)
|
||||
(unless (< maximum low) (errorf #f "~s maximum didn't do better than low" fmt))))
|
||||
(compress-file-test 'lz4)
|
||||
(compress-file-test 'gzip)
|
||||
#t)
|
||||
)
|
||||
|
||||
(mat compression
|
||||
(parameters [compress-format 'gzip] [compress-format 'lz4])
|
||||
(parameters [compress-format 'gzip 'lz4] [compress-level 'low 'medium 'high 'maximum])
|
||||
(and (memq (compress-format) '(gzip lz4)) #t)
|
||||
(and (memq (compress-level) '(low medium high maximum)) #t)
|
||||
(let ()
|
||||
(define cp
|
||||
(lambda (src dst)
|
||||
|
@ -3072,7 +3127,7 @@
|
|||
)
|
||||
|
||||
(mat compression-textual
|
||||
(parameters [compress-format 'gzip] [compress-format 'lz4])
|
||||
(parameters [compress-format 'gzip 'lz4] [compress-level 'low 'medium 'high 'maximum])
|
||||
(let ()
|
||||
(define cp
|
||||
(lambda (src dst)
|
||||
|
|
14
mats/mat.ss
14
mats/mat.ss
|
@ -20,12 +20,16 @@
|
|||
(define-syntax mat
|
||||
(lambda (x)
|
||||
(syntax-case x (parameters)
|
||||
[(_ x (parameters [param val] ...) e ...)
|
||||
#'(for-each (lambda (p v)
|
||||
[(_ x (parameters [param val ...] ...) e ...)
|
||||
#'(let f ([p* (list param ...)] [v** (list (list val ...) ...)])
|
||||
(if (null? p*)
|
||||
(mat x e ...)
|
||||
(let ([p (car p*)])
|
||||
(for-each
|
||||
(lambda (v)
|
||||
(parameterize ([p v])
|
||||
(mat x e ...)))
|
||||
(list param ...)
|
||||
(list val ...))]
|
||||
(f (cdr p*) (cdr v**))))
|
||||
(car v**)))))]
|
||||
[(_ x e ...)
|
||||
(with-syntax ([(source ...)
|
||||
(map (lambda (clause)
|
||||
|
|
167
mats/record.ms
167
mats/record.ms
|
@ -9045,69 +9045,87 @@
|
|||
(#2%list #f (#2%record-type-sealed? rtd))))))
|
||||
)
|
||||
|
||||
(mat cp0-kar-kons-$record-ref-optimizations
|
||||
(eq? (let ()
|
||||
(define-record kons (kar kdr))
|
||||
(#3%$record-ref (make-kons 'a 'b) 0))
|
||||
'a)
|
||||
(equivalent-expansion?
|
||||
(parameterize ([optimize-level 2] [enable-cp0 #t] [#%$suppress-primitive-inlining #f])
|
||||
(expand/optimize
|
||||
'(let ()
|
||||
(define-record kons (kar kdr))
|
||||
(#3%$record-ref (make-kons 'a 'b) 0))))
|
||||
''a)
|
||||
(eq? (let ()
|
||||
(define-record kons (kar kdr))
|
||||
(#3%$record-ref (make-kons 'a 'b) 1))
|
||||
'b)
|
||||
(equivalent-expansion?
|
||||
(parameterize ([optimize-level 2] [enable-cp0 #t] [#%$suppress-primitive-inlining #f])
|
||||
(expand/optimize
|
||||
'(let ()
|
||||
(define-record kons (kar kdr))
|
||||
(#3%$record-ref (make-kons 'a 'b) 1))))
|
||||
''b)
|
||||
(define (cp0x3 cp0 x)
|
||||
(cp0 (cp0 (cp0 x))))
|
||||
|
||||
(define (member? o l)
|
||||
(and (member o l) #t))
|
||||
|
||||
(mat cp0-kar-kons-optimizations
|
||||
; for now, it's necesary to run cp0 three times to complete the reduction
|
||||
(equal?
|
||||
(with-output-to-string
|
||||
(lambda ()
|
||||
(define-record kons (kar kdr))
|
||||
(display (#3%$record-ref (make-kons (begin (display 1) (display 2) 3)
|
||||
(begin (display 4) (display 5) 6))
|
||||
0))))
|
||||
"45123") ;"12453" is also correct
|
||||
(define-record mybox (val))
|
||||
(display (mybox-val (begin (display 1) (make-mybox 2))))))
|
||||
"12")
|
||||
(equivalent-expansion?
|
||||
(parameterize ([optimize-level 2] [enable-cp0 #t] [#%$suppress-primitive-inlining #f])
|
||||
(parameterize ([optimize-level 2] [enable-cp0 #t] [run-cp0 cp0x3] [#%$suppress-primitive-inlining #f])
|
||||
(expand/optimize
|
||||
'(let ()
|
||||
(define-record mybox (val))
|
||||
(display (mybox-val (begin (display 1) (make-mybox 2)))))))
|
||||
'(#2%display
|
||||
(begin
|
||||
(#2%display 1)
|
||||
2)))
|
||||
(eq? (let ()
|
||||
(define-record kons (kar kdr))
|
||||
(kons-kar (make-kons 'a 'b)))
|
||||
'a)
|
||||
(equivalent-expansion?
|
||||
(parameterize ([optimize-level 2] [enable-cp0 #t] [run-cp0 cp0x3] [#%$suppress-primitive-inlining #f])
|
||||
(expand/optimize
|
||||
'(let ()
|
||||
(define-record kons (kar kdr))
|
||||
(kons-kar (make-kons 'a 'b)))))
|
||||
''a)
|
||||
(eq? (let ()
|
||||
(define-record kons (kar kdr))
|
||||
(kons-kdr (make-kons 'a 'b)))
|
||||
'b)
|
||||
(equivalent-expansion?
|
||||
(parameterize ([optimize-level 2] [enable-cp0 #t] [run-cp0 cp0x3] [#%$suppress-primitive-inlining #f])
|
||||
(expand/optimize
|
||||
'(let ()
|
||||
(define-record kons (kar kdr))
|
||||
(kons-kdr (make-kons 'a 'b)))))
|
||||
''b)
|
||||
(member?
|
||||
(with-output-to-string
|
||||
(lambda ()
|
||||
(define-record kons (kar kdr))
|
||||
(display (kons-kar (make-kons (begin (display 1) (display 2) 3)
|
||||
(begin (display 4) (display 5) 6))))))
|
||||
'("45123" "12453"))
|
||||
(equivalent-expansion?
|
||||
(parameterize ([optimize-level 2] [enable-cp0 #t] [run-cp0 cp0x3] [#%$suppress-primitive-inlining #f])
|
||||
(expand/optimize
|
||||
'(let ()
|
||||
(define-record kons (kar kdr))
|
||||
(display (#3%$record-ref (make-kons (begin (display 1) (display 2) 3)
|
||||
(begin (display 4) (display 5) 6))
|
||||
0)))))
|
||||
'(#2%display
|
||||
(display (kons-kar (make-kons (begin (display 1) (display 2) 3)
|
||||
(begin (display 4) (display 5) 6)))))))
|
||||
'(#2%display
|
||||
(begin
|
||||
(#2%display 4)
|
||||
(#2%display 5)
|
||||
(#2%display 1)
|
||||
(#2%display 2)
|
||||
3)))
|
||||
(equal?
|
||||
(member?
|
||||
(with-output-to-string
|
||||
(lambda ()
|
||||
(define-record kons (kar kdr))
|
||||
(display (#3%$record-ref (make-kons (begin (display 1) (display 2) 3)
|
||||
(begin (display 4) (display 5) 6))
|
||||
1))))
|
||||
"45126") ;"12456" is also correct
|
||||
(display (kons-kdr (make-kons (begin (display 1) (display 2) 3)
|
||||
(begin (display 4) (display 5) 6))))))
|
||||
'("45126" "12456"))
|
||||
(equivalent-expansion?
|
||||
(parameterize ([optimize-level 2] [enable-cp0 #t] [#%$suppress-primitive-inlining #f])
|
||||
(parameterize ([optimize-level 2] [enable-cp0 #t] [run-cp0 cp0x3] [#%$suppress-primitive-inlining #f])
|
||||
(expand/optimize
|
||||
'(let ()
|
||||
(define-record kons (kar kdr))
|
||||
(display (#3%$record-ref (make-kons (begin (display 1) (display 2) 3)
|
||||
(begin (display 4) (display 5) 6))
|
||||
1)))))
|
||||
(display (kons-kdr (make-kons (begin (display 1) (display 2) 3)
|
||||
(begin (display 4) (display 5) 6)))))))
|
||||
'(#2%display
|
||||
(begin
|
||||
(#2%display 4)
|
||||
|
@ -9115,43 +9133,48 @@
|
|||
(#2%display 1)
|
||||
(#2%display 2)
|
||||
6)))
|
||||
|
||||
(equal?
|
||||
(with-output-to-string
|
||||
(lambda ()
|
||||
(define-record kons (kar kdr))
|
||||
(display (#3%$record-ref (begin (display 1) (make-kons 2 3))
|
||||
(begin (display 4) 0)))))
|
||||
"412") ;"142" is also correct
|
||||
(define-record ktail (kar (immutable kdr)))
|
||||
(define x (make-ktail 1 2))
|
||||
(display 3)
|
||||
(display (ktail-kdr (begin (display 4) x)))))
|
||||
"342")
|
||||
(equivalent-expansion?
|
||||
(parameterize ([optimize-level 2] [enable-cp0 #t] [#%$suppress-primitive-inlining #f])
|
||||
(parameterize ([optimize-level 2] [enable-cp0 #t] [run-cp0 cp0x3] [#%$suppress-primitive-inlining #f])
|
||||
(expand/optimize
|
||||
'(let ()
|
||||
(define-record kons (kar kdr))
|
||||
(display (#3%$record-ref (begin (display 1) (make-kons 2 3))
|
||||
(begin (display 4) 0))))))
|
||||
'(#2%display
|
||||
(begin
|
||||
(#2%display 4)
|
||||
(#2%display 1)
|
||||
2)))
|
||||
(define-record ktail (kar (immutable kdr)))
|
||||
(define x (make-ktail 1 2))
|
||||
(display 3)
|
||||
(display (ktail-kdr (begin (display 4) x))))))
|
||||
'(begin
|
||||
(#2%display 3)
|
||||
(#2%display
|
||||
(begin
|
||||
(#2%display 4)
|
||||
2))))
|
||||
(equal?
|
||||
(with-output-to-string
|
||||
(lambda ()
|
||||
(define-record kons (kar kdr))
|
||||
(display (#3%$record-ref (begin (display 1) (make-kons 2 3))
|
||||
(begin (display 4) 1)))))
|
||||
"413") ;"143" is also correct
|
||||
(equivalent-expansion?
|
||||
(parameterize ([optimize-level 2] [enable-cp0 #t] [#%$suppress-primitive-inlining #f])
|
||||
(expand/optimize
|
||||
'(let ()
|
||||
(define-record kons (kar kdr))
|
||||
(display (#3%$record-ref (begin (display 1) (make-kons 2 3))
|
||||
(begin (display 4) 1))))))
|
||||
'(#2%display
|
||||
(begin
|
||||
(#2%display 4)
|
||||
(#2%display 1)
|
||||
3)))
|
||||
(define-record ktail (kar (immutable kdr)))
|
||||
(define x (make-ktail 1 2))
|
||||
(display 3)
|
||||
(display (ktail-kar (begin (display 4) x)))))
|
||||
"341")
|
||||
(not (equivalent-expansion?
|
||||
(parameterize ([optimize-level 2] [enable-cp0 #t] [run-cp0 cp0x3] [#%$suppress-primitive-inlining #f])
|
||||
(expand/optimize
|
||||
'(let ()
|
||||
(define-record ktail (kar (immutable kdr)))
|
||||
(define x (make-ktail 1 2))
|
||||
(display 3)
|
||||
(display (ktail-kar (begin (display 4) x))))))
|
||||
'(begin
|
||||
(#2%display 3)
|
||||
(#2%display
|
||||
(begin
|
||||
(#2%display 4)
|
||||
1)))))
|
||||
)
|
||||
|
|
|
@ -3656,9 +3656,6 @@ bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress:
|
|||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: "hello" is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8()".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8(0 0 0 0 0 0 ...)".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: uncompressed #vu8(0 0 0 0 0 0 ...) is larger than expected size".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: uncompressed size 5 for #vu8(0 0 0 0 0 0 ...) is smaller than expected size 6".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8(0 0 0 0 0 0 ...)".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: bytevector #vu8(255 255 255 255 255 255 ...) claims invalid uncompressed size <int>".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-compress: 7 is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-compress: "hello" is not a bytevector".
|
||||
|
@ -3666,9 +3663,6 @@ bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress:
|
|||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: "hello" is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8()".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8(0 0 0 0 0 0 ...)".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: internal error uncompressing #vu8(128 0 0 0 0 0 ...)".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: uncompressed size 5 for #vu8(128 0 0 0 0 0 ...) is smaller than expected size 6".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8(0 0 0 0 0 0 ...)".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: bytevector #vu8(255 255 255 255 255 255 ...) claims invalid uncompressed size <int>".
|
||||
misc.mo:Expected error in mat compiler1: "variable i-am-not-bound is not bound".
|
||||
misc.mo:Expected error in mat compiler1: "attempt to apply non-procedure oops".
|
||||
|
@ -6865,6 +6859,22 @@ io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: 0
|
|||
io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: -15 is not a positive fixnum".
|
||||
io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: <int> is not a positive fixnum".
|
||||
io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: 1024.0 is not a positive fixnum".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-format: foo is not a supported format".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-format: "gzip" is not a supported format".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-level: foo is not a supported level".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-level: 1 is not a supported level".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
|
|
|
@ -3626,8 +3626,12 @@ bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress:
|
|||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: "hello" is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8()".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8(0 0 0 0 0 0 ...)".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: uncompressed #vu8(0 0 0 0 0 0 ...) is larger than expected size".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: uncompressed size 5 for #vu8(0 0 0 0 0 0 ...) is smaller than expected size 6".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: bytevector #vu8(255 255 255 255 255 255 ...) claims invalid uncompressed size <int>".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-compress: 7 is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-compress: "hello" is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: 7 is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: "hello" is not a bytevector".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8()".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: invalid data in source bytevector #vu8(0 0 0 0 0 0 ...)".
|
||||
bytevector.mo:Expected error in mat bytevector-compress: "bytevector-uncompress: bytevector #vu8(255 255 255 255 255 255 ...) claims invalid uncompressed size <int>".
|
||||
misc.mo:Expected error in mat compiler1: "variable i-am-not-bound is not bound".
|
||||
|
@ -6808,6 +6812,24 @@ io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: 0
|
|||
io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: -15 is not a positive fixnum".
|
||||
io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: <int> is not a positive fixnum".
|
||||
io.mo:Expected error in mat custom-port-buffer-size: "custom-port-buffer-size: 1024.0 is not a positive fixnum".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-format: foo is not a supported format".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-format: "gzip" is not a supported format".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-level: foo is not a supported level".
|
||||
io.mo:Expected error in mat compress-parameters: "compress-level: 1 is not a supported level".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: #<output port string> is not a file port".
|
||||
io.mo:Expected error in mat compression: "port-file-compressed!: cannot compress input/output port #<binary input/output port testfile.ss>".
|
||||
io.mo:Expected error in mat bytevector-input-port: "incorrect argument count in call (open-bytevector-input-port)".
|
||||
|
|
|
@ -112,16 +112,29 @@ unordered by default. An ordered guardian's objects are classified as
|
|||
inaccessible only when they are not reachable from the represetative
|
||||
of any inaccessible object in any other guardian.
|
||||
|
||||
\subsection{Compression format (9.5.3)}
|
||||
\subsection{Compression format and level (9.5.3)}
|
||||
|
||||
The default format for compressed-file writing is now LZ4, while {\tt
|
||||
Support for LZ4 compression has been added.
|
||||
LZ4 is now the default format when compressing files (including
|
||||
object files produced by the compiler) and bytevectors, while {\tt
|
||||
gzip} is still supported and can be enabled by setting
|
||||
\scheme{compress-format} to \scheme{'gzip}. Reading in compressed mode
|
||||
the new \scheme{compress-format} parameter to the symbol \scheme{gzip} instead of the
|
||||
default \scheme{lz4}. Reading in compressed mode
|
||||
infers the format, so reading {\tt gzip}-compressed files will still
|
||||
work without changing \scheme{compress-format}. Reading LZ4-format
|
||||
files tends to be much faster than reading {\tt gzip}-format files, in
|
||||
most cases nearly eliminating the load-time cost of compressing
|
||||
compiled files.
|
||||
work without changing \scheme{compress-format}. Reading LZ4-format
|
||||
files tends to be much faster than reading {\tt gzip}-format files,
|
||||
while {\tt gzip}-compressed files tend to be smaller.
|
||||
In particular, object files created by the compiler now tend to be
|
||||
larger but load more quickly.
|
||||
|
||||
The new \scheme{compress-level} parameter can be used to control
|
||||
the amount of time spent on file compression (but not
|
||||
bytevector compression).
|
||||
It can be set to one of the symbols \scheme{low},
|
||||
\scheme{medium}, \scheme{high}, and \scheme{maximum}, which are
|
||||
listed in order from shortest to longest compression time and least
|
||||
to greatest effectiveness.
|
||||
The default value is \scheme{medium}.
|
||||
|
||||
\subsection{Mutexes and condition variables can have names (9.5.3)}
|
||||
|
||||
|
@ -1736,6 +1749,16 @@ in fasl files does not generally make sense.
|
|||
%-----------------------------------------------------------------------------
|
||||
\section{Bug Fixes}\label{section:bugfixes}
|
||||
|
||||
\subsection{Multiplying $-2^{30}$ with itself on 64-bit platforms (9.5.3)}
|
||||
|
||||
A bug that produced the wrong sign when multiplying $-2^{30}$ with
|
||||
itself on 64-bit platforms has been fixed.
|
||||
|
||||
\subsection{Compiler dropping affects from record-accessor calls (9.5.3)}
|
||||
|
||||
A bug that could cause the source optimizer to drop effects within
|
||||
the argument of a record-accessor call has been fixed.
|
||||
|
||||
\subsection{Welcome text in macOS package file (9.5.2)}
|
||||
|
||||
The welcome text and copyright year in the macOS package file was
|
||||
|
|
47
s/Mf-base
47
s/Mf-base
|
@ -24,15 +24,23 @@ o = 3
|
|||
# d is the debug level at which the system should be built
|
||||
d = 0
|
||||
|
||||
# cl (xcl) determines the commonization level
|
||||
# cl determines the commonization level
|
||||
cl = (commonization-level)
|
||||
|
||||
# i determines whether inspector-information is generated: f for false, t for true
|
||||
i = f
|
||||
|
||||
# cp0 (xcp0) determines the number of cp0 (source optimizer) iterations run
|
||||
# cp0 determines the number of cp0 (source optimizer) iterations run
|
||||
cp0 = 2
|
||||
xcp0 = 2
|
||||
|
||||
# cc determines whether compiled files are compressed
|
||||
cc = t
|
||||
|
||||
# xf determines the compression foramt
|
||||
xf = (compress-format)
|
||||
|
||||
# xl determine the compression level
|
||||
xl = (compress-level)
|
||||
|
||||
# p (xp) determines whether source profiling is enabled: f for false, t for true.
|
||||
p = f
|
||||
|
@ -214,6 +222,9 @@ clean: profileclean
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(when #$p (compile-profile (quote source)))'\
|
||||
'(when #$(bp) (compile-profile (quote block)))'\
|
||||
'(when #$(loadspd) (profile-load-data "${ProfileDumpSource}"))'\
|
||||
|
@ -238,6 +249,9 @@ clean: profileclean
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(when #$p (compile-profile (quote source)))'\
|
||||
'(when #$(bp) (compile-profile (quote block)))'\
|
||||
'(when #$(loadspd) (profile-load-data "${ProfileDumpSource}"))'\
|
||||
|
@ -265,6 +279,9 @@ clean: profileclean
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
'(subset-mode (quote system))'\
|
||||
'(compile-file "$*.ss" "$*.so")'\
|
||||
|
@ -275,6 +292,9 @@ clean: profileclean
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(when #$(xp) (compile-profile (quote source)))'\
|
||||
'(when #$(xbp) (compile-profile (quote block)))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
|
@ -344,6 +364,9 @@ cmacros.so: cmacros.ss machine.def layout.ss
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
'(subset-mode (quote system))'\
|
||||
'(compile-file "$*.ss" "$*.so")'\
|
||||
|
@ -356,6 +379,9 @@ priminfo.so: priminfo.ss primdata.ss cmacros.so
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
'(subset-mode (quote system))'\
|
||||
'(compile-file "$*.ss" "$*.so")'\
|
||||
|
@ -369,6 +395,9 @@ mkheader.so: mkheader.ss cmacros.so primvars.so env.so
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
'(subset-mode (quote system))'\
|
||||
'(compile-file "$*.ss" "$*.so")'\
|
||||
|
@ -381,6 +410,9 @@ nanopass.so: $(shell echo ../nanopass/nanopass/*) ../nanopass/nanopass.ss
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
'(collect-trip-bytes (expt 2 24))'\
|
||||
'(collect-request-handler (lambda () (collect 0 1)))'\
|
||||
|
@ -404,6 +436,9 @@ script.all makescript:
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(when #$p (compile-profile (quote source)))'\
|
||||
'(when #$(bp) (compile-profile (quote block)))'\
|
||||
'(when #$(loadspd) (profile-load-data "${ProfileDumpSource}"))'\
|
||||
|
@ -440,6 +475,9 @@ script-static.all:
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(when #$p (compile-profile (quote source)))'\
|
||||
'(when #$(bp) (compile-profile (quote block)))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
|
@ -462,6 +500,9 @@ script-dynamic.all:
|
|||
'(optimize-level $o)'\
|
||||
'(debug-level $d)'\
|
||||
'(commonization-level $(cl))'\
|
||||
'(compile-compressed #$(cc))'\
|
||||
'(compress-format $(xf))'\
|
||||
'(compress-level $(xl))'\
|
||||
'(when #$p (compile-profile (quote source)))'\
|
||||
'(when #$(bp) (compile-profile (quote block)))'\
|
||||
'(generate-inspector-information #$i)'\
|
||||
|
|
38
s/back.ss
38
s/back.ss
|
@ -163,12 +163,38 @@
|
|||
x)))
|
||||
|
||||
(define-who compress-format
|
||||
($make-thread-parameter
|
||||
'lz4
|
||||
(lambda (x)
|
||||
(unless (or (eq? x 'lz4) (eq? x 'gzip))
|
||||
($oops who "~s is not a supported format" x))
|
||||
x)))
|
||||
(case-lambda
|
||||
[()
|
||||
(let ([x ($tc-field 'compress-format ($tc))])
|
||||
(cond
|
||||
[(eqv? x (constant COMPRESS-GZIP)) 'gzip]
|
||||
[(eqv? x (constant COMPRESS-LZ4)) 'lz4]
|
||||
[else ($oops who "unexpected $compress-format value ~s" x)]))]
|
||||
[(x)
|
||||
($tc-field 'compress-format ($tc)
|
||||
(case x
|
||||
[(gzip) (constant COMPRESS-GZIP)]
|
||||
[(lz4) (constant COMPRESS-LZ4)]
|
||||
[else ($oops who "~s is not a supported format" x)]))]))
|
||||
|
||||
(define-who compress-level
|
||||
(case-lambda
|
||||
[()
|
||||
(let ([x ($tc-field 'compress-level ($tc))])
|
||||
(cond
|
||||
[(eqv? x (constant COMPRESS-LOW)) 'low]
|
||||
[(eqv? x (constant COMPRESS-MEDIUM)) 'medium]
|
||||
[(eqv? x (constant COMPRESS-HIGH)) 'high]
|
||||
[(eqv? x (constant COMPRESS-MAX)) 'maximum]
|
||||
[else ($oops who "unexpected $compress-level value ~s" x)]))]
|
||||
[(x)
|
||||
($tc-field 'compress-level ($tc)
|
||||
(case x
|
||||
[(low) (constant COMPRESS-LOW)]
|
||||
[(medium) (constant COMPRESS-MEDIUM)]
|
||||
[(high) (constant COMPRESS-HIGH)]
|
||||
[(maximum) (constant COMPRESS-MAX)]
|
||||
[else ($oops who "~s is not a supported level" x)]))]))
|
||||
|
||||
(define-who debug-level
|
||||
($make-thread-parameter
|
||||
|
|
|
@ -1454,25 +1454,23 @@
|
|||
)
|
||||
|
||||
(let ()
|
||||
;; Store uncompressed size as u64, using high bit to indicate LZ4:
|
||||
;; Store uncompressed size as u64, using low bits to indicate compression format:
|
||||
(define uncompressed-length-length (ftype-sizeof integer-64))
|
||||
;; Always big-endian, so that compressed data is portable.
|
||||
;; It might be useful somehow that valid compressed data always starts
|
||||
;; with a 0 or 128 byte; otherwise, the expected size would be unrealistically big.
|
||||
(define uncompressed-length-endianness (endianness big))
|
||||
|
||||
(define $bytevector-compress-size
|
||||
(foreign-procedure "(cs)bytevector_compress_size" (iptr boolean) uptr))
|
||||
(foreign-procedure "(cs)bytevector_compress_size" (iptr int) uptr))
|
||||
(define $bytevector-compress
|
||||
(foreign-procedure "(cs)bytevector_compress" (scheme-object iptr iptr scheme-object iptr iptr boolean) scheme-object))
|
||||
(foreign-procedure "(cs)bytevector_compress" (scheme-object iptr iptr scheme-object iptr iptr int) scheme-object))
|
||||
(define $bytevector-uncompress
|
||||
(foreign-procedure "(cs)bytevector_uncompress" (scheme-object iptr iptr scheme-object iptr iptr boolean) scheme-object))
|
||||
(foreign-procedure "(cs)bytevector_uncompress" (scheme-object iptr iptr scheme-object iptr iptr int) scheme-object))
|
||||
|
||||
(set-who! bytevector-compress
|
||||
(lambda (bv)
|
||||
(unless (bytevector? bv) (not-a-bytevector who bv))
|
||||
(let* ([as-gz? (eq? 'gzip (compress-format))]
|
||||
[dest-max-len ($bytevector-compress-size (bytevector-length bv) as-gz?)]
|
||||
(let* ([fmt ($tc-field 'compress-format ($tc))]
|
||||
[dest-max-len ($bytevector-compress-size (bytevector-length bv) fmt)]
|
||||
[dest-alloc-len (min (+ dest-max-len uncompressed-length-length)
|
||||
;; In the unlikely event of a non-fixnum requested size...
|
||||
(constant maximum-bytevector-length))]
|
||||
|
@ -1483,34 +1481,25 @@
|
|||
bv
|
||||
0
|
||||
(bytevector-length bv)
|
||||
as-gz?)])
|
||||
fmt)])
|
||||
(cond
|
||||
[(string? r)
|
||||
($oops who r bv)]
|
||||
[else
|
||||
($bytevector-u64-set! dest-bv 0 (bytevector-length bv) uncompressed-length-endianness who)
|
||||
(unless as-gz? (bytevector-u8-set! dest-bv 0 128)) ; set high bit for LZ4
|
||||
(bytevector-truncate! dest-bv (fx+ r uncompressed-length-length))])))))
|
||||
(let ([tag (bitwise-ior
|
||||
(bitwise-arithmetic-shift-left (bytevector-length bv) (constant COMPRESS-FORMAT-BITS))
|
||||
fmt)])
|
||||
($bytevector-u64-set! dest-bv 0 tag uncompressed-length-endianness who)
|
||||
(bytevector-truncate! dest-bv (fx+ r uncompressed-length-length)))])))))
|
||||
|
||||
(set-who! bytevector-uncompress
|
||||
(lambda (bv)
|
||||
(unless (bytevector? bv) (not-a-bytevector who bv))
|
||||
(unless (>= (bytevector-length bv) uncompressed-length-length)
|
||||
($oops who "invalid data in source bytevector ~s" bv))
|
||||
(let* ([as-gz? (not (fx= 128 (bytevector-u8-ref bv 0)))]
|
||||
[dest-length (cond
|
||||
[as-gz?
|
||||
($bytevector-u64-ref bv 0 uncompressed-length-endianness who)]
|
||||
;; Need to skip high bit; likely can skip first 4 bytes
|
||||
[(and (fx= 0 (bytevector-u8-ref bv 1))
|
||||
(fx= 0 (bytevector-u8-ref bv 2))
|
||||
(fx= 0 (bytevector-u8-ref bv 3)))
|
||||
($bytevector-u32-ref bv 4 uncompressed-length-endianness who)]
|
||||
[else
|
||||
;; Clear high bit the hard way
|
||||
(+ ($bytevector-u32-ref bv 4 uncompressed-length-endianness who)
|
||||
(let ([v ($bytevector-u32-ref bv 0 uncompressed-length-endianness who)])
|
||||
((bitwise-arithmetic-shift-left (- v #x80000000) 32))))])])
|
||||
(let* ([tag ($bytevector-u64-ref bv 0 uncompressed-length-endianness who)]
|
||||
[fmt (logand tag (fx- (fxsll 1 (constant COMPRESS-FORMAT-BITS)) 1))]
|
||||
[dest-length (bitwise-arithmetic-shift-right tag (constant COMPRESS-FORMAT-BITS))])
|
||||
(unless (and (fixnum? dest-length)
|
||||
($fxu< dest-length (constant maximum-bytevector-length)))
|
||||
($oops who "bytevector ~s claims invalid uncompressed size ~s" bv dest-length))
|
||||
|
@ -1521,7 +1510,7 @@
|
|||
bv
|
||||
uncompressed-length-length
|
||||
(fx- (bytevector-length bv) uncompressed-length-length)
|
||||
as-gz?)])
|
||||
fmt)])
|
||||
(cond
|
||||
[(string? r) ($oops who r bv)]
|
||||
[(fx= r dest-length) dest-bv]
|
||||
|
|
12
s/cmacros.ss
12
s/cmacros.ss
|
@ -534,6 +534,15 @@
|
|||
|
||||
(define-constant SEOF -1)
|
||||
|
||||
(define-constant COMPRESS-GZIP 0)
|
||||
(define-constant COMPRESS-LZ4 1)
|
||||
(define-constant COMPRESS-FORMAT-BITS 3)
|
||||
|
||||
(define-constant COMPRESS-LOW 0)
|
||||
(define-constant COMPRESS-MEDIUM 1)
|
||||
(define-constant COMPRESS-HIGH 2)
|
||||
(define-constant COMPRESS-MAX 3)
|
||||
|
||||
(define-constant SICONV-DUNNO 0)
|
||||
(define-constant SICONV-INVALID 1)
|
||||
(define-constant SICONV-INCOMPLETE 2)
|
||||
|
@ -1404,6 +1413,9 @@
|
|||
[ptr suppress-primitive-inlining]
|
||||
[ptr default-record-equal-procedure]
|
||||
[ptr default-record-hash-procedure]
|
||||
[ptr compress-format]
|
||||
[ptr compress-level]
|
||||
[void* lz4-out-buffer]
|
||||
[U64 instr-counter]
|
||||
[U64 alloc-counter]
|
||||
[ptr parameters]))
|
||||
|
|
25
s/cp0.ss
25
s/cp0.ss
|
@ -4991,26 +4991,27 @@
|
|||
(cp0 rtd-expr 'ignored env sc wd #f moi)
|
||||
(map (lambda (e) (cp0 e 'ignored env sc wd #f moi)) e*)))
|
||||
true-rec)])]
|
||||
[(record-ref ,rtd ,type ,index ,e)
|
||||
[(record-ref ,rtd ,type ,index ,e0)
|
||||
(context-case ctxt
|
||||
[(effect ignored) (make-nontail ctxt (cp0 e 'ignored env sc wd name moi))]
|
||||
[(effect ignored) (make-nontail ctxt (cp0 e0 'ignored env sc wd name moi))]
|
||||
[else
|
||||
(let ([e (cp0 e 'value env sc wd name moi)])
|
||||
(or (nanopass-case (Lsrc Expr) (result-exp e)
|
||||
(let ([e0 (cp0 e0 'value env sc wd name moi)])
|
||||
(or (nanopass-case (Lsrc Expr) (result-exp e0)
|
||||
[(quote ,d)
|
||||
(and (record? d rtd)
|
||||
(make-seq ctxt e `(quote ,((csv7:record-field-accessor rtd index) d))))]
|
||||
(make-seq ctxt e0 `(quote ,((csv7:record-field-accessor rtd index) d))))]
|
||||
[(record ,rtd1 ,rtd-expr ,e* ...)
|
||||
(let loop ([e* e*] [re* '()] [index index])
|
||||
(and (not (null? e*))
|
||||
(if (= index 0)
|
||||
(if (fx= index 0)
|
||||
(let ([e (car e*)] [e* (rappend re* (cdr e*))])
|
||||
(if (null? e*)
|
||||
(make-nontail ctxt e)
|
||||
(make-1seq ctxt (make-seq* 'ignored e*) (make-nontail ctxt e))))
|
||||
(non-result-exp e0
|
||||
(if (null? e*)
|
||||
(make-nontail ctxt e)
|
||||
(make-1seq ctxt (make-seq* 'ignored e*) (make-nontail ctxt e)))))
|
||||
(loop (cdr e*) (cons (car e*) re*) (fx- index 1)))))]
|
||||
[else #f])
|
||||
(nanopass-case (Lsrc Expr) (result-exp/indirect-ref e)
|
||||
(nanopass-case (Lsrc Expr) (result-exp/indirect-ref e0)
|
||||
[(record ,rtd1 ,rtd-expr ,e* ...)
|
||||
(and (> (length e*) index)
|
||||
(not (fld-mutable? (list-ref (rtd-flds rtd) index)))
|
||||
|
@ -5021,9 +5022,9 @@
|
|||
[,pr (all-set? (prim-mask proc) (primref-flags pr))]
|
||||
[else #f])
|
||||
; recur to cp0 to get inlining, folding, etc.
|
||||
(cp0 e ctxt env sc wd name moi))))]
|
||||
(non-result-exp e0 (cp0 e ctxt env sc wd name moi)))))]
|
||||
[else #f])
|
||||
(begin (bump sc 1) `(record-ref ,rtd ,type ,index ,e))))])]
|
||||
(begin (bump sc 1) `(record-ref ,rtd ,type ,index ,e0))))])]
|
||||
[(record-set! ,rtd ,type ,index ,[cp0 : e1 'value env sc wd #f moi -> e1] ,[cp0 : e2 'value env sc wd #f moi -> e2])
|
||||
`(record-set! ,rtd ,type ,index ,e1 ,e2)]
|
||||
[(record-type ,rtd ,e) (cp0 e ctxt env sc wd name moi)]
|
||||
|
|
254
s/cpnanopass.ss
254
s/cpnanopass.ss
|
@ -3881,61 +3881,65 @@
|
|||
(if (null? e*)
|
||||
e
|
||||
(reduce #f (moi src sexpr (list e (car e*))) (cdr e*)))))))))
|
||||
(define-who relop-length
|
||||
(lambda (op e1 e2)
|
||||
(define (mirror op)
|
||||
(case op
|
||||
[(<) '>]
|
||||
[(<=) '>=]
|
||||
[(>=) '<=]
|
||||
[(>) '<]
|
||||
[else op]))
|
||||
(define go
|
||||
(lambda (n e r?)
|
||||
(define op-error
|
||||
(lambda (op)
|
||||
(sorry! who "unexpected op ~s" op)))
|
||||
(let ([op (if r? (mirror op) op)])
|
||||
(let f ([n n] [e e])
|
||||
(if (fx= n 0)
|
||||
(case op
|
||||
[(= <=) (build-null? e)]
|
||||
[(<) `(seq ,e (quote #f))]
|
||||
[(>) (build-not (build-null? e))]
|
||||
[(>=) `(seq ,e (quote #t))]
|
||||
[else (op-error op)])
|
||||
(case op
|
||||
[(= >) (bind #t (e)
|
||||
(build-and
|
||||
(build-not (build-null? e))
|
||||
(f (fx- n 1) (build-cdr e))))]
|
||||
[(<) (if (fx= n 1)
|
||||
(build-null? e)
|
||||
(bind #t (e)
|
||||
(build-simple-or
|
||||
(build-null? e)
|
||||
(f (fx- n 1) (build-cdr e)))))]
|
||||
[(<=) (bind #t (e)
|
||||
(build-simple-or
|
||||
(build-null? e)
|
||||
(f (fx- n 1) (build-cdr e))))]
|
||||
[(>=) (if (fx= n 1)
|
||||
(build-not (build-null? e))
|
||||
(bind #t (e)
|
||||
(build-and
|
||||
(build-not (build-null? e))
|
||||
(f (fx- n 1) (build-cdr e)))))]
|
||||
[else (op-error op)]))))))
|
||||
(define try
|
||||
(lambda (e1 e2 r?)
|
||||
(nanopass-case (L7 Expr) e1
|
||||
[(call ,info ,mdcl ,pr ,e)
|
||||
(guard (and (eq? (primref-name pr) 'length) (all-set? (prim-mask unsafe) (primref-flags pr))))
|
||||
(nanopass-case (L7 Expr) e2
|
||||
[(quote ,d) (and (fixnum? d) (fx<= 0 d 4) (go d e r?))]
|
||||
[else #f])]
|
||||
[else #f])))
|
||||
(or (try e1 e2 #f) (try e2 e1 #t))))
|
||||
(module (relop-length RELOP< RELOP<= RELOP= RELOP>= RELOP>)
|
||||
(define RELOP< -2)
|
||||
(define RELOP<= -1)
|
||||
(define RELOP= 0)
|
||||
(define RELOP>= 2)
|
||||
(define RELOP> 1)
|
||||
(define (mirror op) (fx- op))
|
||||
(define go
|
||||
(lambda (op e n)
|
||||
(let f ([n n] [e e])
|
||||
(if (fx= n 0)
|
||||
(cond
|
||||
[(or (eqv? op RELOP=) (eqv? op RELOP<=)) (build-null? e)]
|
||||
[(eqv? op RELOP<) `(seq ,e (quote #f))]
|
||||
[(eqv? op RELOP>) (build-not (build-null? e))]
|
||||
[(eqv? op RELOP>=) `(seq ,e (quote #t))]
|
||||
[else (sorry! 'relop-length "unexpected op ~s" op)])
|
||||
(cond
|
||||
[(or (eqv? op RELOP=) (eqv? op RELOP>))
|
||||
(bind #t (e)
|
||||
(build-and
|
||||
(build-not (build-null? e))
|
||||
(f (fx- n 1) (build-cdr e))))]
|
||||
[(eqv? op RELOP<)
|
||||
(if (fx= n 1)
|
||||
(build-null? e)
|
||||
(bind #t (e)
|
||||
(build-simple-or
|
||||
(build-null? e)
|
||||
(f (fx- n 1) (build-cdr e)))))]
|
||||
[(eqv? op RELOP<=)
|
||||
(bind #t (e)
|
||||
(build-simple-or
|
||||
(build-null? e)
|
||||
(f (fx- n 1) (build-cdr e))))]
|
||||
[(eqv? op RELOP>=)
|
||||
(if (fx= n 1)
|
||||
(build-not (build-null? e))
|
||||
(bind #t (e)
|
||||
(build-and
|
||||
(build-not (build-null? e))
|
||||
(f (fx- n 1) (build-cdr e)))))]
|
||||
[else (sorry! 'relop-length "unexpected op ~s" op)])))))
|
||||
(define relop-length1
|
||||
(lambda (op e n)
|
||||
(nanopass-case (L7 Expr) e
|
||||
[(call ,info ,mdcl ,pr ,e)
|
||||
(guard (and (eq? (primref-name pr) 'length) (all-set? (prim-mask unsafe) (primref-flags pr))))
|
||||
(go op e n)]
|
||||
[else #f])))
|
||||
(define relop-length2
|
||||
(lambda (op e1 e2)
|
||||
(nanopass-case (L7 Expr) e2
|
||||
[(quote ,d) (and (fixnum? d) (fx<= 0 d 4) (relop-length1 op e1 d))]
|
||||
[else #f])))
|
||||
(define relop-length
|
||||
(case-lambda
|
||||
[(op e) (relop-length1 op e 0)]
|
||||
[(op e1 e2) (or (relop-length2 op e1 e2) (relop-length2 (mirror op) e1 e2))])))
|
||||
(define make-ftype-pointer-equal?
|
||||
(lambda (e1 e2)
|
||||
(bind #f (e1 e2)
|
||||
|
@ -3977,7 +3981,9 @@
|
|||
(define-inline 2 $value
|
||||
[(e) (ensure-single-valued e #f)])
|
||||
(define-inline 2 eq?
|
||||
[(e1 e2) (%inline eq? ,e1 ,e2)])
|
||||
[(e1 e2)
|
||||
(or (relop-length RELOP= e1 e2)
|
||||
(%inline eq? ,e1 ,e2))])
|
||||
(define-inline 2 $keep-live
|
||||
[(e) (%seq ,(%inline keep-live ,e) ,(%constant svoid))])
|
||||
(let ()
|
||||
|
@ -3990,7 +3996,7 @@
|
|||
(build-libcall #t src sexpr fx=? e1 e2)
|
||||
(build-libcall #t src sexpr fx= e1 e2)))))
|
||||
(define (go src sexpr e1 e2 r6rs?)
|
||||
(or (relop-length '= e1 e2)
|
||||
(or (relop-length RELOP= e1 e2)
|
||||
(cond
|
||||
[(constant? (lambda (x) (eqv? x 0)) e1)
|
||||
(bind #t (e2) (zgo src sexpr e2 e1 e2 r6rs?))]
|
||||
|
@ -4014,7 +4020,7 @@
|
|||
[(_ op r6rs:op length-op inline-op)
|
||||
(let ()
|
||||
(define (go src sexpr e1 e2 r6rs?)
|
||||
(or (relop-length 'length-op e1 e2)
|
||||
(or (relop-length length-op e1 e2)
|
||||
(bind #t (e1 e2)
|
||||
`(if ,(build-fixnums? (list e1 e2))
|
||||
,(%inline inline-op ,e1 ,e2)
|
||||
|
@ -4031,17 +4037,17 @@
|
|||
; TODO: 3-operand case requires 3-operand library routine
|
||||
#; [(e1 e2 e3) (go3 src sexpr e1 e2 e3 #t)]
|
||||
[(e1 e2 . e*) #f]))]))
|
||||
(fx-pred fx< fx<? < <)
|
||||
(fx-pred fx<= fx<=? <= <=)
|
||||
(fx-pred fx>= fx>=? >= >=)
|
||||
(fx-pred fx> fx>? > >))
|
||||
(fx-pred fx< fx<? RELOP< <)
|
||||
(fx-pred fx<= fx<=? RELOP<= <=)
|
||||
(fx-pred fx>= fx>=? RELOP>= >=)
|
||||
(fx-pred fx> fx>? RELOP> >))
|
||||
(let () ; level 3 fx=, fx=?, etc.
|
||||
(define-syntax fx-pred
|
||||
(syntax-rules ()
|
||||
[(_ op r6rs:op length-op inline-op)
|
||||
(let ()
|
||||
(define (go e1 e2)
|
||||
(or (relop-length 'length-op e1 e2)
|
||||
(or (relop-length length-op e1 e2)
|
||||
(%inline inline-op ,e1 ,e2)))
|
||||
(define reducer
|
||||
(if (eq? 'inline-op 'eq?)
|
||||
|
@ -4054,11 +4060,11 @@
|
|||
(define-inline 3 r6rs:op
|
||||
[(e1 e2) (go e1 e2)]
|
||||
[(e1 e2 . e*) (reducer src sexpr moi e1 e2 e*)]))]))
|
||||
(fx-pred fx< fx<? < <)
|
||||
(fx-pred fx<= fx<=? <= <=)
|
||||
(fx-pred fx= fx=? = eq?)
|
||||
(fx-pred fx>= fx>=? >= >=)
|
||||
(fx-pred fx> fx>? > >))
|
||||
(fx-pred fx< fx<? RELOP< <)
|
||||
(fx-pred fx<= fx<=? RELOP<= <=)
|
||||
(fx-pred fx= fx=? RELOP= eq?)
|
||||
(fx-pred fx>= fx>=? RELOP>= >=)
|
||||
(fx-pred fx> fx>? RELOP> >))
|
||||
(let () ; level 3 fxlogand, ...
|
||||
(define-syntax fxlogop
|
||||
(syntax-rules ()
|
||||
|
@ -4159,7 +4165,7 @@
|
|||
(fxlognotop fxlognot)
|
||||
(fxlognotop fxnot))
|
||||
(define-inline 3 $fxu<
|
||||
[(e1 e2) (or (relop-length '< e1 e2)
|
||||
[(e1 e2) (or (relop-length RELOP< e1 e2)
|
||||
(%inline u< ,e1 ,e2))])
|
||||
(define-inline 3 fx+
|
||||
[() `(immediate 0)]
|
||||
|
@ -4604,15 +4610,15 @@
|
|||
(build-libcall #t src sexpr fxcopy-bit e1 e2)))]
|
||||
[else #f]))]))
|
||||
(define-inline 3 fxzero?
|
||||
[(e) (%inline eq? ,e (immediate 0))])
|
||||
[(e) (or (relop-length RELOP= e) (%inline eq? ,e (immediate 0)))])
|
||||
(define-inline 3 fxpositive?
|
||||
[(e) (%inline > ,e (immediate 0))])
|
||||
[(e) (or (relop-length RELOP> e) (%inline > ,e (immediate 0)))])
|
||||
(define-inline 3 fxnonnegative?
|
||||
[(e) (%inline >= ,e (immediate 0))])
|
||||
[(e) (or (relop-length RELOP>= e) (%inline >= ,e (immediate 0)))])
|
||||
(define-inline 3 fxnegative?
|
||||
[(e) (%inline < ,e (immediate 0))])
|
||||
[(e) (or (relop-length RELOP< e) (%inline < ,e (immediate 0)))])
|
||||
(define-inline 3 fxnonpositive?
|
||||
[(e) (%inline <= ,e (immediate 0))])
|
||||
[(e) (or (relop-length RELOP<= e) (%inline <= ,e (immediate 0)))])
|
||||
(define-inline 3 fxeven?
|
||||
[(e) (%inline eq?
|
||||
,(%inline logand ,e (immediate ,(fix 1)))
|
||||
|
@ -4623,32 +4629,37 @@
|
|||
(immediate ,(fix 1)))])
|
||||
|
||||
(define-inline 2 fxzero?
|
||||
[(e) (bind #t (e)
|
||||
(build-simple-or
|
||||
(%inline eq? ,e (immediate 0))
|
||||
`(if ,(build-fixnums? (list e))
|
||||
,(%constant sfalse)
|
||||
,(build-libcall #t src sexpr fxzero? e))))])
|
||||
[(e) (or (relop-length RELOP= e)
|
||||
(bind #t (e)
|
||||
(build-simple-or
|
||||
(%inline eq? ,e (immediate 0))
|
||||
`(if ,(build-fixnums? (list e))
|
||||
,(%constant sfalse)
|
||||
,(build-libcall #t src sexpr fxzero? e)))))])
|
||||
(define-inline 2 fxpositive?
|
||||
[(e) (bind #t (e)
|
||||
`(if ,(build-fixnums? (list e))
|
||||
,(%inline > ,e (immediate 0))
|
||||
,(build-libcall #t src sexpr fxpositive? e)))])
|
||||
[(e) (or (relop-length RELOP> e)
|
||||
(bind #t (e)
|
||||
`(if ,(build-fixnums? (list e))
|
||||
,(%inline > ,e (immediate 0))
|
||||
,(build-libcall #t src sexpr fxpositive? e))))])
|
||||
(define-inline 2 fxnonnegative?
|
||||
[(e) (bind #t (e)
|
||||
`(if ,(build-fixnums? (list e))
|
||||
,(%inline >= ,e (immediate 0))
|
||||
,(build-libcall #t src sexpr fxnonnegative? e)))])
|
||||
[(e) (or (relop-length RELOP>= e)
|
||||
(bind #t (e)
|
||||
`(if ,(build-fixnums? (list e))
|
||||
,(%inline >= ,e (immediate 0))
|
||||
,(build-libcall #t src sexpr fxnonnegative? e))))])
|
||||
(define-inline 2 fxnegative?
|
||||
[(e) (bind #t (e)
|
||||
`(if ,(build-fixnums? (list e))
|
||||
,(%inline < ,e (immediate 0))
|
||||
,(build-libcall #t src sexpr fxnegative? e)))])
|
||||
[(e) (or (relop-length RELOP< e)
|
||||
(bind #t (e)
|
||||
`(if ,(build-fixnums? (list e))
|
||||
,(%inline < ,e (immediate 0))
|
||||
,(build-libcall #t src sexpr fxnegative? e))))])
|
||||
(define-inline 2 fxnonpositive?
|
||||
[(e) (bind #t (e)
|
||||
`(if ,(build-fixnums? (list e))
|
||||
,(%inline <= ,e (immediate 0))
|
||||
,(build-libcall #t src sexpr fxnonpositive? e)))])
|
||||
[(e) (or (relop-length RELOP<= e)
|
||||
(bind #t (e)
|
||||
`(if ,(build-fixnums? (list e))
|
||||
,(%inline <= ,e (immediate 0))
|
||||
,(build-libcall #t src sexpr fxnonpositive? e))))])
|
||||
(define-inline 2 fxeven?
|
||||
[(e) (bind #t (e)
|
||||
`(if ,(build-fixnums? (list e))
|
||||
|
@ -6085,6 +6096,7 @@
|
|||
(define eqvnever? (e*ok? eqvnever-help?))
|
||||
(define-inline 2 eqv?
|
||||
[(e1 e2) (or (eqvop-null-fptr e1 e2)
|
||||
(relop-length RELOP= e1 e2)
|
||||
(eqvop-flonum e1 e2)
|
||||
(eqvop-flonum e2 e1)
|
||||
(if (or (eqok? e1) (eqok? e2)
|
||||
|
@ -6116,6 +6128,7 @@
|
|||
[else #f])))
|
||||
(define-inline 2 equal?
|
||||
[(e1 e2) (or (eqvop-null-fptr e1 e2)
|
||||
(relop-length RELOP= e1 e2)
|
||||
(xform-equal? src sexpr e1 e2)
|
||||
(xform-equal? src sexpr e2 e1))]))
|
||||
(let ()
|
||||
|
@ -6580,7 +6593,7 @@
|
|||
,(build-libcall #t src sexpr = e1 e2))))
|
||||
(define (go src sexpr e1 e2)
|
||||
(or (eqvop-null-fptr e1 e2)
|
||||
(relop-length '= e1 e2)
|
||||
(relop-length RELOP= e1 e2)
|
||||
(cond
|
||||
[(constant? (lambda (x) (eqv? x 0)) e1)
|
||||
(bind #t (e2) (zgo src sexpr e2 e1 e2))]
|
||||
|
@ -6603,7 +6616,7 @@
|
|||
(let ()
|
||||
(define builder
|
||||
(lambda (e1 e2 libcall)
|
||||
(or (relop-length 'relop e1 e2)
|
||||
(or (relop-length relop e1 e2)
|
||||
(bind #t (e1 e2)
|
||||
`(if ,(build-fixnums? (list e1 e2))
|
||||
,(%inline op ,e1 ,e2)
|
||||
|
@ -6620,33 +6633,38 @@
|
|||
(lambda (e1 e2) (build-libcall #t src sexpr name e1 e2)))]
|
||||
; TODO: handle 3-operand case w/3-operand library routine
|
||||
[(e1 e2 . e*) #f]))]))
|
||||
(define-relop-inline < r6rs:< < <)
|
||||
(define-relop-inline <= r6rs:<= <= <=)
|
||||
(define-relop-inline >= r6rs:>= >= >=)
|
||||
(define-relop-inline > r6rs:> > >))
|
||||
(define-relop-inline < r6rs:< RELOP< <)
|
||||
(define-relop-inline <= r6rs:<= RELOP<= <=)
|
||||
(define-relop-inline >= r6rs:>= RELOP>= >=)
|
||||
(define-relop-inline > r6rs:> RELOP> >))
|
||||
(define-inline 3 positive? ; 3 so opt-level 2 errors come from positive?
|
||||
[(e) (handle-prim src sexpr 3 '> (list e `(quote 0)))])
|
||||
(define-inline 3 nonnegative? ; 3 so opt-level 2 errors come from positive?
|
||||
(define-inline 3 nonnegative? ; 3 so opt-level 2 errors come from nonnegative?
|
||||
[(e) (handle-prim src sexpr 3 '>= (list e `(quote 0)))])
|
||||
(define-inline 3 negative? ; 3 so opt-level 2 errors come from positive?
|
||||
(define-inline 3 negative? ; 3 so opt-level 2 errors come from negative?
|
||||
[(e) (handle-prim src sexpr 3 '< (list e `(quote 0)))])
|
||||
(define-inline 3 nonpositive? ; 3 so opt-level 2 errors come from positive?
|
||||
(define-inline 3 nonpositive? ; 3 so opt-level 2 errors come from nonpositive?
|
||||
[(e) (handle-prim src sexpr 3 '<= (list e `(quote 0)))])
|
||||
(define-inline 2 zero?
|
||||
[(e)
|
||||
(nanopass-case (L7 Expr) e
|
||||
[(call ,info ,mdcl ,pr ,e)
|
||||
(guard
|
||||
(eq? (primref-name pr) 'ftype-pointer-address)
|
||||
(all-set? (prim-mask unsafe) (primref-flags pr)))
|
||||
(make-ftype-pointer-null? e)]
|
||||
[else
|
||||
(bind #t (e)
|
||||
(build-simple-or
|
||||
(%inline eq? ,e (immediate ,(fix 0)))
|
||||
`(if ,(%type-check mask-fixnum type-fixnum ,e)
|
||||
,(%constant sfalse)
|
||||
,(build-libcall #t src sexpr zero? e))))])])
|
||||
(or (relop-length RELOP= e)
|
||||
(nanopass-case (L7 Expr) e
|
||||
[(call ,info ,mdcl ,pr ,e)
|
||||
(guard
|
||||
(eq? (primref-name pr) 'ftype-pointer-address)
|
||||
(all-set? (prim-mask unsafe) (primref-flags pr)))
|
||||
(make-ftype-pointer-null? e)]
|
||||
[else
|
||||
(bind #t (e)
|
||||
(build-simple-or
|
||||
(%inline eq? ,e (immediate ,(fix 0)))
|
||||
`(if ,(%type-check mask-fixnum type-fixnum ,e)
|
||||
,(%constant sfalse)
|
||||
,(build-libcall #t src sexpr zero? e))))]))])
|
||||
(define-inline 2 positive? [(e) (relop-length RELOP> e)])
|
||||
(define-inline 2 nonnegative? [(e) (relop-length RELOP>= e)])
|
||||
(define-inline 2 negative? [(e) (relop-length RELOP< e)])
|
||||
(define-inline 2 nonpositive? [(e) (relop-length RELOP<= e)])
|
||||
(let ()
|
||||
(define-syntax define-logorop-inline
|
||||
(syntax-rules ()
|
||||
|
|
|
@ -608,9 +608,9 @@ TODO:
|
|||
|
||||
(define (error-help warning? who whoarg message irritants basecond)
|
||||
(unless (or (eq? whoarg #f) (string? whoarg) (symbol? whoarg))
|
||||
($oops who "invalid who argument ~s" whoarg))
|
||||
($oops who "invalid who argument ~s (message = ~s, irritants = ~s)" whoarg message irritants))
|
||||
(unless (string? message)
|
||||
($oops who "invalid message argument ~s" message))
|
||||
($oops who "invalid message argument ~s (who = ~s, irritants = ~s)" message whoarg irritants))
|
||||
(let ([c (if whoarg
|
||||
(if irritants
|
||||
(condition basecond
|
||||
|
@ -640,7 +640,9 @@ TODO:
|
|||
(lambda (whoarg message . irritants)
|
||||
(error-help #f who whoarg message irritants favcond)))
|
||||
|
||||
(set! $oops assertion-violationf)
|
||||
(set-who! $oops
|
||||
(lambda (whoarg message . irritants)
|
||||
(error-help #f who whoarg message irritants favcond)))
|
||||
|
||||
(set-who! $oops/c
|
||||
(lambda (whoarg basecond message . irritants)
|
||||
|
|
22
s/io.ss
22
s/io.ss
|
@ -264,7 +264,7 @@ implementation notes:
|
|||
(foreign-procedure "(cs)new_open_output_fd"
|
||||
(string int
|
||||
boolean boolean boolean
|
||||
boolean boolean boolean boolean boolean)
|
||||
boolean boolean boolean boolean)
|
||||
scheme-object))
|
||||
(define $open-input/output-fd
|
||||
(foreign-procedure "(cs)new_open_input_output_fd"
|
||||
|
@ -310,7 +310,7 @@ implementation notes:
|
|||
(define $compress-input-fd
|
||||
(foreign-procedure "(cs)compress_input_fd" (int integer-64) scheme-object))
|
||||
(define $compress-output-fd
|
||||
(foreign-procedure "(cs)compress_output_fd" (int boolean) scheme-object))
|
||||
(foreign-procedure "(cs)compress_output_fd" (int) scheme-object))
|
||||
(module (clear-open-files register-open-file registered-open-file? unregister-open-file)
|
||||
(define open-files #f)
|
||||
(define file-guardian)
|
||||
|
@ -645,14 +645,17 @@ implementation notes:
|
|||
|
||||
(define binary-file-port-close-port
|
||||
(lambda (who p)
|
||||
(unregister-open-file p)
|
||||
(let ([msg ($close-fd ($port-info p) (port-gz-mode p))])
|
||||
(unless (eq? #t msg) (port-oops who p msg)))
|
||||
(mark-port-closed! p)
|
||||
(when (input-port? p)
|
||||
(set-port-eof! p #f)
|
||||
(set-binary-port-input-size! p 0))
|
||||
(when (output-port? p) (set-binary-port-output-size! p 0))))
|
||||
(when (output-port? p) (set-binary-port-output-size! p 0))
|
||||
(unregister-open-file p)
|
||||
; mark port closed before closing fd. if an interrupt occurs, we'd prefer
|
||||
; that the fd's resources never be freed than to have an open port floating
|
||||
; around with fd resources that have already been freed.
|
||||
(mark-port-closed! p)
|
||||
(let ([msg ($close-fd ($port-info p) (port-gz-mode p))])
|
||||
(unless (eq? #t msg) (port-oops who p msg)))))
|
||||
|
||||
(define-syntax binary-file-port-port-position
|
||||
(syntax-rules ()
|
||||
|
@ -3185,7 +3188,7 @@ implementation notes:
|
|||
; reposition to 'unread' any compressed data in the input buffer
|
||||
(set-port-position! p fp)
|
||||
($compress-input-fd fd fp))
|
||||
($compress-output-fd fd (eq? (compress-format) 'gzip)))])
|
||||
($compress-output-fd fd))])
|
||||
(when (string? gzfd) ($oops who "failed for ~s: ~(~a~)" p gzfd))
|
||||
(unless (eqv? gzfd fd) ; uncompressed input port
|
||||
(assert (box? gzfd))
|
||||
|
@ -4091,8 +4094,7 @@ implementation notes:
|
|||
(let ([fd (critical-section
|
||||
($open-output-fd filename perms
|
||||
no-create no-fail no-truncate
|
||||
append lock replace compressed
|
||||
(and compressed (eq? (compress-format) 'gzip))))])
|
||||
append lock replace compressed))])
|
||||
(when (pair? fd) (open-oops who filename options fd))
|
||||
(open-binary-fd-output-port who filename fd #t b-mode lock compressed)))))
|
||||
|
||||
|
|
|
@ -927,6 +927,7 @@
|
|||
(compile-profile [sig [() -> (ptr)] [(ptr) -> (void)]] [flags unrestricted])
|
||||
(compile-program-handler [sig [() -> (procedure)] [(procedure) -> (void)]] [flags])
|
||||
(compress-format [sig [() -> (symbol)] [(sub-symbol) -> (void)]] [flags])
|
||||
(compress-level [sig [() -> (symbol)] [(sub-symbol) -> (void)]] [flags])
|
||||
(console-error-port [sig [() -> (textual-output-port)] [(textual-output-port) -> (void)]] [flags])
|
||||
(console-input-port [sig [() -> (textual-input-port)] [(textual-input-port) -> (void)]] [flags])
|
||||
(console-output-port [sig [() -> (textual-output-port)] [(textual-output-port) -> (void)]] [flags])
|
||||
|
@ -1749,7 +1750,6 @@
|
|||
($address-in-heap? [flags])
|
||||
($address->object [flags])
|
||||
($allocate-thread-parameter [feature pthreads] [flags alloc])
|
||||
($annotation-options [flags])
|
||||
($apply [flags])
|
||||
($assembly-output [flags])
|
||||
($as-time-goes-by [flags])
|
||||
|
@ -1851,10 +1851,8 @@
|
|||
($fasl-file-equal? #;[sig [(pathname pathname) (pathname pathname ptr) -> (boolean)]] [flags])
|
||||
($fasl-out [flags])
|
||||
($fasl-start [flags])
|
||||
($fasl-strip-options [flags])
|
||||
($fasl-table [flags])
|
||||
($fasl-wrf-graph [flags])
|
||||
($file-options [flags])
|
||||
($filter-conv [flags])
|
||||
($filter-foreign-type [flags])
|
||||
($fixed-path? [flags])
|
||||
|
@ -2087,7 +2085,6 @@
|
|||
($keep-live [flags])
|
||||
($last-new-vector-element [flags])
|
||||
($lexical-error [flags])
|
||||
($library-requirements-options [flags])
|
||||
($library-search [flags])
|
||||
($list-length [flags single-valued])
|
||||
($load-library [flags])
|
||||
|
@ -2310,6 +2307,13 @@
|
|||
($xscript-port? [flags])
|
||||
)
|
||||
|
||||
(define-symbol-flags* ([libraries] [flags system]) ; system options sets
|
||||
($annotation-options [flags])
|
||||
($fasl-strip-options [flags])
|
||||
($file-options [flags])
|
||||
($library-requirements-options [flags])
|
||||
)
|
||||
|
||||
(define-symbol-flags* ([libraries] [flags system proc]) ; system parameters
|
||||
($block-counter [flags])
|
||||
($cafe [flags])
|
||||
|
|
8
s/x86.ss
8
s/x86.ss
|
@ -1555,13 +1555,13 @@
|
|||
(record-case dest-ea
|
||||
[(index) (size index-reg base-reg)
|
||||
(cond
|
||||
[(and (eqv? size 0) (not (eq? base-reg %ebp))) #f]
|
||||
[(and (eqv? 0 size) (not (eq? base-reg %ebp))) #f]
|
||||
[(ax-byte-size? size) (build byte size)]
|
||||
[else (build long size)])]
|
||||
[(literal@) stuff (cons 'abs stuff)]
|
||||
[(disp) (size reg)
|
||||
(cond
|
||||
[(and (eqv? size 0) (not (eq? reg %ebp))) #f] ; indirect
|
||||
[(and (eqv? 0 size) (not (eq? reg %ebp))) #f] ; indirect
|
||||
[(ax-byte-size? size) (build byte size)]
|
||||
[else (build long size)])]
|
||||
[(reg) r #f]
|
||||
|
@ -1611,13 +1611,13 @@
|
|||
(record-case dest-ea
|
||||
[(index) (size index-reg base-reg)
|
||||
(cond
|
||||
[(and (eqv? size 0) (not (eq? base-reg %ebp))) #b00]
|
||||
[(and (eqv? 0 size) (not (eq? base-reg %ebp))) #b00]
|
||||
[(ax-byte-size? size) #b01]
|
||||
[else #b10])]
|
||||
[(literal@) stuff #b00]
|
||||
[(disp) (size reg)
|
||||
(cond
|
||||
[(and (eqv? size 0) (not (eq? reg %ebp))) #b00] ; indirect
|
||||
[(and (eqv? 0 size) (not (eq? reg %ebp))) #b00] ; indirect
|
||||
[(ax-byte-size? size) #b01]
|
||||
[else #b10])]
|
||||
[(reg) r #b11]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
VERSION := 9.5.3
|
||||
WIXEXTENSIONS := -ext WixUIExtension -ext WixBalExtension
|
||||
export MSYS_NO_PATHCONV=1
|
||||
|
||||
ChezScheme.exe: x86/bundle.wixobj ChezScheme32.msi ChezScheme64.msi
|
||||
cmd.exe /c light.bat -nologo $(WIXEXTENSIONS) $< -out $@
|
||||
|
|
Loading…
Reference in New Issue
Block a user