Native code implementing bytevector accessors uses the following access pattern: *(intNN_t*)(base+offset) This can result in so called "unaligned memory access" if the offset is not a multiple of 2, 4, 8, or if the base address has not been allocated at an aligned address (unlikely). Most popular modern architectures--x86 and ARMs--allow unaligned memory accesses on the instruction level but they are typically performed a bit slower than properly aligned accesses. On the other hand, there are architectures which do not allow unaligned memory accesses. Each load or store of a value longer than 1 byte should use properly aligned address on those architectures. That is, u16 should be loaded from even addresses, s32 should only be stored at an address which is a multiple of 4, and f64 (aka double) can be located only at addresses which are multiple of 8. If the address is not aligned, CPU raises an exception which typically results in the process being killed by the operating system with a SIGBUS signal. SPARC is one of those architectures which are strict with alignment. The current access pattern in bytevector native code can result in unaligned accesses, which in turn results in crashes. This issue has been found in this way: Chibi test suite includes some tests for unaligned accesses and it failed on SPARC. In order to avoid unaligned accesses, loads and stores need to be performed a bit differently, doing 'type punning' in a safe way, not just casting pointers which breaks strict aliasing rules. The most portable and efficient way to do this is to use memcpy(). Compilers know about this trick and generate very efficient code here, avoiding the function call and using the most efficient instructions. (Obviously, only when optimizations are enabled.) That is, given static inline uint32_t ref_u32(const void* p) { uint32_t v; memcpy(&v, p, sizeof(v)); return v; } on x86 this will be compiled into a single "movl" instruction because x86 allows unaligned accesses, similar with ARM where this becomes a single "ldr" instruction. However, on RISC-V--another platform with strict alignment rules--this code compiles into 4 "lbu" instructions fetching 4 bytes, then some more arithmetic to stitch those bytes into a single 32-bit value. |
||
---|---|---|
.githooks | ||
.github/workflows | ||
benchmarks | ||
build-lib/chibi/char-set | ||
contrib | ||
data | ||
doc | ||
examples | ||
include/chibi | ||
js | ||
lib | ||
opt | ||
tests | ||
tools | ||
.gitignore | ||
.hgignore | ||
.travis.yml | ||
appveyor.yml | ||
AUTHORS | ||
bignum.c | ||
chibi-scheme.pc.in | ||
CMakeLists.txt | ||
configure | ||
COPYING | ||
eval.c | ||
fedora.spec | ||
gc.c | ||
gc_heap.c | ||
main.c | ||
Makefile | ||
Makefile.detect | ||
Makefile.libs | ||
mkfile | ||
opcodes.c | ||
plan9.c | ||
README-win32.md | ||
README.libs | ||
README.md | ||
RELEASE | ||
sexp.c | ||
simplify.c | ||
TODO | ||
VERSION | ||
vm.c |
Minimal Scheme Implementation for use as an Extension Language
http://synthcode.com/wiki/chibi-scheme
Chibi-Scheme is a very small library intended for use as an extension and scripting language in C programs. In addition to support for lightweight VM-based threads, each VM itself runs in an isolated heap allowing multiple VMs to run simultaneously in different OS threads.
There are no external dependencies so is relatively easy to drop into any project.
Despite the small size, Chibi-Scheme attempts to do The Right Thing. The default settings include:
- a full numeric tower, with rational and complex numbers
- full and seamless Unicode support
- low-level and high-level hygienic macros
- an extensible module system
Specifically, the default repl language contains all bindings from
R7RS small, available explicitly as the
(scheme small)
library. The language is built in layers, however -
see the manual for instructions on compiling with fewer features or
requesting a smaller language on startup.
Chibi-Scheme is known to work on 32 and 64-bit Linux, FreeBSD, NetBSD, OpenBSD and OS X, Plan 9, Windows, iOS, Android, ARM and Emscripten. Basic support for native Windows desktop also exists. See README-win32.md for details and build instructions.
To build on most platforms just run make && make test
. This has a
few conditionals assuming GNU make. If using another make, there are
a few parameters in Makefile.detect you need to set by hand.
This will provide a shared library libchibi-scheme, as well as a sample chibi-scheme command-line repl. You can then run
sudo make install
to install the binaries and libraries. You can optionally specify a PREFIX for the installation directory:
make PREFIX=/path/to/install/
sudo make PREFIX=/path/to/install/ install
By default files are installed in /usr/local.
If you want to try out chibi-scheme without installing, be sure to set
LD_LIBRARY_PATH
so it can find the shared libraries.
For more detailed documentation, run make doc
and see the generated
doc/chibi.html.