import from compiler2

This commit is contained in:
Abdulaziz Ghuloum 2006-11-23 19:40:06 -05:00
parent 3e7726203a
commit bd94bedc04
66 changed files with 4447 additions and 23873 deletions

View File

@ -1,2 +1,8 @@
stst: stst.s scheme.c scheme_asm.s runtime-5.4.c collect-5.7.c libtoplevel.s libcxr.s -luuid libsymboltable-5.6.s libhandlers-5.5.s libcontrol-5.8.s libintelasm-5.8.s libcollect-5.3.s librecord-5.6.s libcore-5.7.s libio-5.8.s libwriter-5.7.s libtokenizer-5.7.s libexpand-5.8.s libinterpret-5.8.s libcafe-5.8.s libtrace-5.3.s libposix-5.3.s
gcc -Wall -o stst stst.s scheme.c scheme_asm.s runtime-5.4.c collect-5.7.c libtoplevel.s libcxr.s -luuid libsymboltable-5.6.s libhandlers-5.5.s libcontrol-5.8.s libintelasm-5.8.s libcollect-5.3.s librecord-5.6.s libcore-5.7.s libio-5.8.s libwriter-5.7.s libtokenizer-5.7.s libexpand-5.8.s libinterpret-5.8.s libcafe-5.8.s libtrace-5.3.s libposix-5.3.s
all: ikarus.fasl
ikarus.fasl:
echo '(load "compiler-6.1.ss")' | petite
clean:
rm -f *.fasl

View File

@ -1 +1 @@
2006-07-27
2006-07-28

View File

@ -1,839 +0,0 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <assert.h>
#include <uuid/uuid.h>
#include "scheme.h"
typedef struct root_t{
int count;
char** start;
struct root_t* next;
} root_t;
void S_add_roots(pcb_t* pcb, int* f){
int n = *f;
if(n == 0) return;
root_t* t = malloc(sizeof(root_t));
if(t == NULL){
fprintf(stderr, "Error mallocing\n");
exit(-1);
}
t->count = n;
t->start = (char**)(f+1);
t->next = (root_t*) pcb->roots;
pcb->roots = (char*) t;
int i;
for(i=1; i<=n; i++){
assert(f[i] == 0);
}
}
void S_check_roots(pcb_t* pcb, int* f){
int n = *f;
int i;
for(i=1; i<=n; i++){
assert(f[i] != 0);
}
}
/* S_collect is called from scheme under the following conditions:
* 1. An attempt is made to allocate a small object and the ap is above
* the red line.
* 2. The current frame of the call is dead, so, upon return from S_collect,
* the caller returns to its caller.
* 3. The frame-pointer of the caller to S_collect is saved at
* pcb->stack_extent. No variables are live at that frame except for
* the return point (at *(pcb->stack_extent)).
* 4. S_collect must return a new ap (in pcb->allocation_pointer) that has
* at least 2 pages of memory free.
* 5. S_collect must also update pcb->allocaton_red_line to be 2 pages below
* the real end of heap.
* 6. S_collect should not move the stack.
*/
#define pagesize 4096
#define pageshift 12
#define minimum_heap_size (pagesize * 1024 * 4)
#define maximum_heap_size (pagesize * 1024 * 8)
#define minimum_stack_size (pagesize * 128)
#define align_to_page(x) (((x)/pagesize)*pagesize)
#define align_to_next_page(x) \
(((pagesize - 1 + (unsigned int)(x)) >> pageshift) << pageshift)
#define align_to_prev_page(x) \
((((unsigned int)(x)) >> pageshift) << pageshift)
static char* allocate_unprotected_space(int size);
static void deallocate_unprotected_space(char* p, int size);
static void deallocate_string_pages(char*);
static void copy_roots(pcb_t* pcb);
static char* move_object(char* x, pcb_t* pcb);
pcb_t* S_collect(int req, pcb_t* pcb){
#if 0
fprintf(stderr, "S_collect entry %d (pcb=0x%08x)\n", req, (int)pcb);
#endif
char* heap_base = pcb->heap_base;
#if 0
int heap_size = (int)pcb->heap_size;
fprintf(stderr, "heapsize=0x%08x (0x%08x .. 0x%08x)\n",
heap_size,
(int) heap_base,
(int) (heap_base + heap_size - 1));
#endif
int used_space = (int)(pcb->allocation_pointer - heap_base);
{
int bytes = (int) pcb->allocated_bytes + (used_space & 0xFFFFF);
pcb->allocated_megs += (bytes >> 20);
pcb->allocated_bytes = (char*) (bytes & 0xFFFFF);
#if 0
fprintf(stderr, "allocated %d megs and %d bytes so far\n",
(int) pcb->allocated_megs,
(int) pcb->allocated_bytes);
#endif
}
int required_space = align_to_page(used_space + 2 * req + 2 * pagesize);
if(required_space < minimum_heap_size){
required_space = minimum_heap_size;
}
if(required_space > maximum_heap_size){
fprintf(stderr, "Maximum heapsize exceeded\n");
exit(-1);
}
char* old_heap = pcb->heap_base;
int old_size = (int)pcb->heap_size;
char* old_string_pages = pcb->string_pages;
pcb->string_pages = 0;
char* new_heap = allocate_unprotected_space(maximum_heap_size);
pcb->allocation_pointer = new_heap;
pcb->allocation_redline = new_heap + maximum_heap_size - 2 * pagesize;
pcb->heap_base = new_heap;
pcb->heap_size = (char*) maximum_heap_size;
copy_roots(pcb);
char** p = (char**) new_heap;
while(p != (char**) pcb->allocation_pointer){
*p = move_object(*p, pcb);
p++;
}
deallocate_unprotected_space(old_heap, old_size);
deallocate_string_pages(old_string_pages);
{
int free_space =
(int)pcb->allocation_redline - (int)pcb->allocation_pointer;
int diff = align_to_page(free_space - minimum_heap_size);
if(diff > 0){
deallocate_unprotected_space(
pcb->heap_base + (int)pcb->heap_size - diff,
diff);
pcb->allocation_redline -= diff;
pcb->heap_size -= diff;
}
}
#if 0
fprintf(stderr, "ap=0x%08x limit=0x%08x\n",
(int)pcb->allocation_pointer,
(int)pcb->heap_base+(int)pcb->heap_size-wordsize);
#endif
return pcb;
}
#define fixnump(x) ((((int)(x)) & fx_mask) == fx_tag)
#define closurep(x) ((((int)(x)) & closure_mask) == closure_tag)
#define immediatep(x) ((((int)(x)) & 7) == 7)
#define tagof(x) (((int) (x)) & 7)
#define ref(x,t) (*((char**)(((char*)(x))+((int)(t)))))
#define align(x) ((((x)+object_alignment-1)>>align_shift)<<align_shift)
typedef struct page_t{
char* base;
char* end;
struct page_t* next;
} page_t;
static page_t* make_page_t(){
page_t* p = malloc(sizeof(page_t));
if(p == NULL){
fprintf(stderr, "failed to allocate page");
exit(-1);
}
return p;
}
static void deallocate_string_pages(char* old_string_pages){
page_t* p;
p = (page_t*) old_string_pages;
while(p){
deallocate_unprotected_space(p->base, p->end - p->base);
p=p->next;
}
p = (page_t*) old_string_pages;
while(p){
page_t* n = p->next;
free(p);
p = n;
}
}
#if 0
static char* extend_pointer_ap(pcb_t* pcb, int size){
if(pcb->pointer_base){
page_t* p = make_page_t();
p->base = pcb->pointer_base;
p->end = pcb->pointer_ap;
p->next = (page_t*) pcb->pointer_pages;
pcb->pointer_pages = (char*) p;
}
char* ap = allocate_unprotected_space(size);
pcb->pointer_base = ap;
pcb->pointer_ap = ap;
pcb->pointer_eap = ap + size;
return ap;
}
#endif
static char* alloc_large_string(pcb_t* pcb, int size){
char* ap = allocate_unprotected_space(size);
page_t* p = make_page_t();
p->base = ap;
p->end = ap+size;
p->next = (page_t*) pcb->string_pages;
pcb->string_pages = (char*) p;
return ap;
}
static char* extend_string_ap(pcb_t* pcb, int size){
if(pcb->string_base){
page_t* p = make_page_t();
p->base = pcb->string_base;
p->end = pcb->string_ap;
p->next = (page_t*) pcb->string_pages;
pcb->string_pages = (char*) p;
}
char* ap = allocate_unprotected_space(size);
pcb->string_base = ap;
pcb->string_ap = ap;
pcb->string_eap = ap + size;
return ap;
}
static char* move_string(char* s, pcb_t* pcb){
int len = (int) ref(s, -string_tag);
int sz = align((len>>fx_shift)+disp_string_data+1);
if(sz < pagesize){
char* ap = pcb->string_ap;
char* nap = ap + sz;
if(nap > pcb->string_eap){
ap = extend_string_ap(pcb, pagesize);
pcb->string_eap = ap + pagesize;
nap = ap + sz;
}
pcb->string_ap = nap;
memcpy(ap, s-string_tag, sz);
ref(s,-string_tag) = (char*)-1;
ref(s,wordsize-string_tag) = ap+string_tag;
return ap + string_tag;
}
else {
char* ap = alloc_large_string(pcb, sz);
memcpy(ap, s-string_tag, sz);
ref(s,-string_tag) = (char*)-1;
ref(s,wordsize-string_tag) = ap+string_tag;
return ap + string_tag;
}
}
static void munch_stack(char* fp, pcb_t* pcb, char* frame_base){
while(fp != frame_base){
assert(fp < frame_base);
#if 0
fprintf(stderr, "copying frame at 0x%08x of 0x%08x\n",
(int)fp, (int)stack_base);
#endif
char* rp = ref(fp, 0);
#if 0
fprintf(stderr, "return-point = 0x%08x\n", (int)rp);
#endif
char* rp_offset = ref(rp, disp_frame_offset);
assert(rp_offset == 0);
int framesize = (int) ref(rp, disp_frame_size); /* UGLY */
assert(fixnump(framesize));
assert(framesize >= 0);
if(framesize > 0){
int bytes_in_mask = ((framesize>>fx_shift)+7)>>3;
char* mask = rp + disp_frame_size - bytes_in_mask;
fp = fp + framesize;
char** fpp = (char**) fp;
int i;
for(i=0; i<bytes_in_mask; i++){
unsigned char m = mask[i];
if(m){
if (m & 0x01) {
fpp[0] = move_object(fpp[0], pcb);
}
if (m & 0x02) {
fpp[-1] = move_object(fpp[-1], pcb);
}
if (m & 0x04) {
fpp[-2] = move_object(fpp[-2], pcb);
}
if (m & 0x08) {
fpp[-3] = move_object(fpp[-3], pcb);
}
if (m & 0x10) {
fpp[-4] = move_object(fpp[-4], pcb);
}
if (m & 0x20) {
fpp[-5] = move_object(fpp[-5], pcb);
}
if (m & 0x40) {
fpp[-6] = move_object(fpp[-6], pcb);
}
if (m & 0x80) {
fpp[-7] = move_object(fpp[-7], pcb);
}
}
fpp -= 8;
}
}
else if(framesize == 0){
framesize = (int)ref(fp, wordsize);
assert(fixnump(framesize));
assert(framesize > 0);
#if 0
/* move cp */
{
char* cp = ref(fp, 2*wordsize);
assert(closurep(cp));
ref(fp, 2*wordsize) = move_object(cp, pcb);
}
#endif
fp += framesize;
int i;
for(i=wordsize; i<(framesize); i+=wordsize){
ref(fp, -i) = move_object(ref(fp,-i), pcb);
}
}
else {
fprintf(stderr, "Error: framesize is %d\n", framesize);
exit(-10);
}
}
}
static char* move_stack(char* s, pcb_t* pcb, int sz){
char* ns;
int asz = align(sz);
if(asz < pagesize){
char* ap = pcb->string_ap;
char* nap = ap + asz;
if(nap > pcb->string_eap){
ap = extend_string_ap(pcb, pagesize);
pcb->string_eap = ap + pagesize;
nap = ap + asz;
}
pcb->string_ap = nap;
ns = ap;
}
else {
ns = alloc_large_string(pcb, asz);
}
memcpy(ns, s, sz);
munch_stack(ns, pcb, ns+sz);
return ns;
}
static char* move_pointers(char* x, pcb_t* pcb, int size, int tag){
int sz = align(size);
char* ap = pcb->allocation_pointer;
char* nap = ap + sz;
pcb->allocation_pointer = nap;
ref(nap, -wordsize) = 0;
memcpy(ap, x, size);
ref(x,0) = (char*)-1;
ref(x,wordsize) = ap + tag;
return ap + tag;
}
static char* move_continuation(char* x, pcb_t* pcb){
int sz = (int) ref(x, disp_continuation_size);
char* top = ref(x, disp_continuation_top);
char* r = move_pointers(x, pcb, continuation_size, vector_tag);
ref(r, disp_continuation_top - vector_tag) = move_stack(top, pcb, sz);
return r;
}
static char* move_code(char* x, pcb_t* pcb){
int instrsize = (int) ref(x, disp_code_instrsize);
if(instrsize == 0){
return (x + vector_tag);
}
int relocsize = (int) ref(x, disp_code_relocsize);
int reqspace = instrsize + relocsize + disp_code_data;
char* nx = allocate_unprotected_space(reqspace);
{
page_t* p = malloc(sizeof(page_t));
if(p == NULL){
fprintf(stderr, "failed to alloc a page_t\n");
exit(-1);
}
p->next = (page_t*) pcb->string_pages;
pcb->string_pages = (char*) p;
p->base = nx;
p->end = nx + reqspace;
}
memcpy(nx, x, reqspace);
ref(x, 0) = (char*)-1;
ref(x, wordsize) = nx + vector_tag;
{
char* p = nx + disp_code_data + instrsize;
char* pe = p + relocsize;
while(p < pe){
int r = (int) ref(p,0);
if(r == 0){
p = pe;
}
else {
int rtag = r & 3;
if(rtag == 0){
/* undisplaced pointer */
int code_offset = r >> 2;
char* old_object = ref(nx, disp_code_data + code_offset);
char* new_object = move_object(old_object, pcb);
ref(nx, disp_code_data + code_offset) = new_object;
p += wordsize;
}
else if(rtag == 1){
/* displaced pointer */
int code_offset = r >> 2;
int object_offset = (int) ref(p, wordsize);
char* old_displaced_object = ref(nx, disp_code_data + code_offset);
char* old_object = old_displaced_object - object_offset;
char* new_object = move_object(old_object, pcb);
char* new_displaced_object = new_object + object_offset;
ref(nx, disp_code_data + code_offset) = new_displaced_object;
p += (2 * wordsize);
}
else if(rtag == 2){
/* displaced relative pointer */
int code_offset = r >> 2;
int relative_offset = (int) ref(p, wordsize);
char* old_relative_pointer = ref(nx, disp_code_data + code_offset);
char* old_relative_object = old_relative_pointer - relative_offset;
char* old_addr = x + disp_code_data + code_offset + wordsize;
char* old_object = old_relative_object + (unsigned int) old_addr;
char* new_object = move_object(old_object, pcb);
char* new_disp_object = new_object + relative_offset;
char* next_word = nx + disp_code_data + code_offset + wordsize;
char* new_relative_pointer =
new_disp_object - (unsigned int) next_word;
ref(next_word, -wordsize) = new_relative_pointer;
p += (2 * wordsize);
}
else {
fprintf(stderr, "invalid rtag %d in 0x%08x\n", rtag, r);
exit(-1);
}
}
}
}
int err = mprotect(nx,
align_to_next_page(reqspace),
PROT_READ | PROT_WRITE | PROT_EXEC);
if(err == -1){
perror("Cannot set code executable");
exit(-1);
}
return nx + vector_tag;
}
static char* move_object(char* x, pcb_t* pcb){
if(fixnump(x)){
return x;
}
else if(immediatep(x)){
return x;
}
else {
int tag = tagof(x);
char* fst = ref(x, -tag);
if(fst == (char*)-1){
return ref(x,wordsize-tag);
}
else if(tag == pair_tag){
return(move_pointers(x-tag, pcb, pair_size, tag));
}
else if(tag == closure_tag){
//assert(ref(fst, -2*wordsize) == 0);
int size = (int) ref(fst, -wordsize);
assert(fixnump(size));
assert(size > 0);
char* new_closure = move_pointers(x-tag, pcb, size, tag);
char* code_entry = ref(new_closure, -closure_tag);
char* code_object = code_entry - disp_code_data + vector_tag;
char* new_code_object = move_object(code_object, pcb);
char* new_code_entry = new_code_object + disp_code_data - vector_tag;
ref(new_closure, -closure_tag) = new_code_entry;
return new_closure;
}
else if(tag == symbol_tag){
return (move_pointers(x-tag, pcb, symbol_size, tag));
}
else if(tag == vector_tag){
if(fixnump(fst)){
return (move_pointers(x-tag, pcb, disp_vector_data + (int)fst, tag));
}
else if(fst == (char*) continuation_tag){
return (move_continuation(x-tag, pcb));
}
else if(fst == (char*) code_tag){
return (move_code(x-tag, pcb));
}
else if(((int)fst & record_pmask) == record_ptag){
int len;
{
char* rtd = fst;
char* rtd_fst = ref(rtd, -record_ptag);
if(rtd_fst == (char*) -1){
rtd = ref(rtd, wordsize-record_ptag);
}
len = (int) ref(rtd, disp_record_data - record_ptag);
}
return (move_pointers(x-tag, pcb, disp_record_data + len, tag));
}
else {
fprintf(stderr, "nonvec 0x%08x 0x%08x\n", (int)x, (int)fst);
exit(-1);
}
}
else if(tag == string_tag){
return (move_string(x, pcb));
}
else {
fprintf(stderr, "here tag=%d\n", tag);
exit(-1);
}
}
}
static void copy_roots(pcb_t* pcb){
/* first, the constants */
root_t* r = (root_t*)pcb->roots;
while(r){
int n = r->count;
char** f = r->start;
int i;
for(i=0; i<n; i++){
f[i] = move_object(f[i], pcb);
}
r = r->next;
}
/* next, the pcb-primitives */
char** fst = &pcb->scheme_objects;
char** end = &pcb->scheme_objects_end;
fst++;
while(fst < end){
*fst = move_object(*fst, pcb);
fst++;
}
/* next, the stack */
char* fp = pcb->frame_pointer;
char* frame_base = pcb->frame_base;
munch_stack(fp, pcb, frame_base);
}
static char* allocate_unprotected_space(int size){
int aligned_size = ((size + pagesize - 1) / pagesize) * pagesize;
char* p = mmap(0, aligned_size,
PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE,
0, 0);
if(p == MAP_FAILED){
perror("allocate_unprotected_space failed to mmap");
exit(-10);
}
return p;
}
static void deallocate_unprotected_space(char* p, int size){
int status;
int aligned_size = ((size + pagesize - 1) / pagesize) * pagesize;
status = munmap(p, aligned_size);
if(status != 0){
perror("deallocate_unprotected_space failed to unmap");
exit(-10);
}
}
void S_stack_overflow(pcb_t* pcb){
// fprintf(stderr, "stack overflow detected\n");
char* stack_top = pcb->stack_top;
int stack_size = (int) pcb->stack_size;
char* fp = pcb->frame_pointer;
char* frame_base = pcb->frame_base;
assert(fp != frame_base);
char* rp = ref(fp, 0);
int framesize = (int) ref(rp, disp_frame_size); /* UGLY */
assert(fixnump(framesize));
assert(framesize >= 0);
if(framesize == 0){
framesize = (int)ref(fp, wordsize);
assert(fixnump(framesize));
}
// fprintf(stderr, "framesize = %d bytes\n", framesize);
{ /* capture continuation */
char* next_frame_top = fp + framesize;
if(next_frame_top == frame_base){
fprintf(stderr, "continuation already captured\n");
} else {
//fprintf(stderr, "capturing continuation ... ");
char* cont = pcb->allocation_pointer;
pcb->allocation_pointer += continuation_size;
ref(cont, 0) = (char*) continuation_tag;
ref(cont, disp_continuation_top) = next_frame_top;
ref(cont, disp_continuation_next) = pcb->next_continuation;
ref(cont, disp_continuation_size) =
frame_base - (int)next_frame_top;
pcb->next_continuation = cont + vector_tag;
//fprintf(stderr, "done (sz=0x%08x)\n",
// (int) ref(cont, disp_continuation_size));
}
}
int req_stack_size = align_to_page(framesize * 4 + 2 * pagesize);
if(req_stack_size < minimum_stack_size){
req_stack_size = minimum_stack_size;
}
char* new_stack = allocate_unprotected_space(req_stack_size);
char* new_frame_redline = new_stack + 2 * pagesize;
char* new_frame_base = new_stack + req_stack_size - wordsize;
ref(new_frame_base, 0) = ref(frame_base, 0); /* underflow handler */
memcpy(new_frame_base - framesize, fp, framesize);
pcb->stack_top = new_stack;
pcb->stack_size = (char*)req_stack_size;
pcb->frame_base = new_frame_base;
pcb->frame_pointer = new_frame_base - framesize;
pcb->frame_redline = new_frame_redline;
/*
fprintf(stderr, "stack=0x%08x .. 0x%08x (redline=0x%08x) fp=0x%08x\n",
(int) pcb->frame_base,
(int) pcb->stack_top,
(int) pcb->frame_redline,
(int) pcb->frame_pointer);
fprintf(stderr, "returning ... \n");
*/
page_t* p = malloc(sizeof(page_t));
if(p == NULL){
fprintf(stderr, "cannot malloc page_t\n");
exit(-1);
}
p->base = stack_top;
p->end = stack_top + stack_size;
p->next = (page_t*) pcb->string_pages;
pcb->string_pages = (char*) p;
//fprintf(stderr, "done\n");
return;
}
/*
On overflow:
+--------------+
| unused |
| area |
| |
+--------------+
| rp | <-- frame pointer on overflow
+--------------+
| frame |
| when |
| overflow |
| occured |
+--------------+
| rp_next | <-- capture next conitnuation here
+--------------+ (unless we're at base already)
| ... |
| ... |
| ... |
+--------------+
| underflow |
+--------------+
New stack:
+--------------+
| unused |
| area |
| |
| |
| |
| |
| |
| |
| |
| |
+--------------+
| rp | <-- frame pointer on return
+--------------+
| frame |
| when |
| overflow |
| occured |
+--------------+
| underflow |
+--------------+
*/
char* S_make_code(int fxcsize, int fxrsize, int fxclsize, pcb_t* pcb){
int csize = fxcsize >> fx_shift;
csize = (((csize + (1 << fx_shift) - 1) >> fx_shift) << fx_shift);
int reqspace = csize + fxrsize + disp_code_data;
char* code = allocate_unprotected_space(reqspace);
{
page_t* p = malloc(sizeof(page_t));
if(p == NULL){
fprintf(stderr, "failed to allocate a page\n");
exit(-1);
}
p->base = code;
p->end = code + reqspace;
p->next = (page_t*) pcb->string_pages;
pcb->string_pages = (char*) p;
}
memset(code, 0, reqspace);
ref(code, 0) = (char*)code_tag;
ref(code, disp_code_instrsize) = (char*) csize;
ref(code, disp_code_relocsize) = (char*) fxrsize;
ref(code, disp_code_closuresize) = (char*) fxclsize;
return(code + vector_tag);
}
char* S_make_code_executable(char* x, pcb_t* pcb){
int instrsize = (int) ref(x, disp_code_instrsize - vector_tag);
char* code_start = x + disp_code_data - vector_tag;
char* code_end = code_start + instrsize;
char* page_start = (char*) align_to_prev_page(code_start);
char* page_end = (char*) align_to_next_page(code_end);
int err = mprotect(page_start,
(int) (page_end - page_start),
PROT_READ | PROT_WRITE | PROT_EXEC);
if(err == -1){
perror("Cannot set code executable");
exit(-1);
}
return bool_t;
}
#if 0
SUPER FAST HASH
Taken from
http://www.azillionmonkeys.com/qed/hash.html
#endif
#undef get16bits
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
#define get16bits(d) (*((const uint16_t *) (d)))
#endif
#if !defined (get16bits)
#define get16bits(d) ((((const uint8_t *)(d))[1] << UINT32_C(8))\
+((const uint8_t *)(d))[0])
#endif
char* SuperFastHash (char* str) {
char* data = str + disp_string_data - string_tag;
int len = (int) ref(str, disp_string_length - string_tag);
len = len >> fx_shift;
uint32_t hash = len, tmp;
int rem;
if (len <= 0 || data == NULL) return 0;
rem = len & 3;
len >>= 2;
/* Main loop */
for (;len > 0; len--) {
hash += get16bits (data);
tmp = (get16bits (data+2) << 11) ^ hash;
hash = (hash << 16) ^ tmp;
data += 2*sizeof (uint16_t);
hash += hash >> 11;
}
/* Handle end cases */
switch (rem) {
case 3: hash += get16bits (data);
hash ^= hash << 16;
hash ^= data[sizeof (uint16_t)] << 18;
hash += hash >> 11;
break;
case 2: hash += get16bits (data);
hash ^= hash << 11;
hash += hash >> 17;
break;
case 1: hash += *data;
hash ^= hash << 10;
hash += hash >> 1;
}
/* Force "avalanching" of final 127 bits */
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return (char*)(hash<<fx_shift);
}
char* S_uuid(char* str){
assert((36 << fx_shift) == (int) ref(str, disp_string_length - string_tag));
uuid_t u;
uuid_clear(u);
uuid_generate(u);
uuid_unparse_upper(u, str + disp_string_data - string_tag);
return str;
}
char* S_fork(){
pid_t pid = fork();
int fxpid = pid << fx_shift;
if(pid != (fxpid >> fx_shift)){
fprintf(stderr, "BUG: pid out of range in fork\n");
exit(-1);
}
return (char*) fxpid;
}
char* S_system(char* str){
int status = system(str + disp_string_data - string_tag);
int fxstatus = status << fx_shift;
if(status != (fxstatus >> fx_shift)){
fprintf(stderr, "BUG: rv out of range in system\n");
exit(-1);
}
return (char*) fxstatus;
}

View File

@ -3888,8 +3888,3 @@
(system "cp stst petite-ikarus-fresh")
(define (asm-helper-code)
)

3132
src/compiler-6.1.ss Normal file

File diff suppressed because it is too large Load Diff

19933
src/dump

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +0,0 @@
all: library1.so library2.so client
library1.so: library1.c
gcc -Wall -shared -o library1.so library1.c
library2.so: library2.c
gcc -Wall -shared -o library2.so library2.c
client: client.c
gcc -Wall -ldl -o client client.c

Binary file not shown.

View File

@ -1,36 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
void do_lib(char* libname){
fprintf(stderr, "loading %s... ", libname);
void* dh = dlopen(libname, RTLD_NOW | RTLD_LOCAL);
if(dh == NULL){
fprintf(stderr, "failed: %s\n", dlerror());
exit(-1);
}
fprintf(stderr, "0x%08x\n", (int)dh);
fprintf(stderr, "loading library_print ... ");
int(*my_print)(char*) = dlsym(dh, "library_print");
if(my_print == NULL){
fprintf(stderr, "failed: %s\n", dlerror());
exit(-1);
}
fprintf(stderr, "0x%08x\n", (int)my_print);
fprintf(stderr, "Calling it ... ");
my_print("Hello There");
fprintf(stderr, "done\n");
}
int main(int argc, char** argv){
do_lib("./library1.so");
do_lib("./library2.so");
do_lib("./library1.so");
return 0;
}

View File

@ -1,8 +0,0 @@
#include <stdio.h>
int library_print(char* x){
fprintf(stderr, "LIB1: %s\n", x);
return 0;
}

View File

@ -1,8 +0,0 @@
#include <stdio.h>
int library_print(char* x){
fprintf(stderr, "LIB2: %s\n", x);
return 0;
}

Binary file not shown.

View File

@ -1,132 +0,0 @@
;;;
;;; the interface for creating and managing code objects
;;;
($pcb-set! make-code
(lambda (code-size reloc-size closure-size)
(unless (and (fixnum? code-size) (fx> code-size 0))
(error 'make-code "invalid code size ~s" code-size))
(unless (and (fixnum? reloc-size) (fx>= reloc-size 0))
(error 'make-code "invalid relocation table size ~s" reloc-size))
(unless (and (fixnum? closure-size) (fx>= closure-size 0))
(error 'make-code "invalid closure size ~s" closure-size))
(foreign-call "S_make_code" code-size reloc-size closure-size)))
($pcb-set! make-code-executable!
(lambda (x)
(unless (code? x) (error 'make-code-executable! "~s is not a code" x))
(unless (foreign-call "S_make_code_executable" x)
(error 'make-code-executable "Failed!"))))
($pcb-set! code-instr-size
(lambda (x)
(unless (code? x)
(error 'code-instr-size "~s is not a code" x))
($code-instr-size x)))
($pcb-set! code-reloc-size
(lambda (x)
(unless (code? x)
(error 'code-reloc-size "~s is not a code" x))
($code-reloc-size x)))
($pcb-set! code-closure-size
(lambda (x)
(unless (code? x)
(error 'code-closure-size "~s is not a code" x))
($code-closure-size x)))
($pcb-set! code?
(lambda (x)
(code? x)))
($pcb-set! code->closure
(lambda (x)
(unless (code? x) (error 'code->closure "~s is not a code"))
(unless ($fx= ($code-closure-size x) 1)
(error 'code->closure "code contains free variables"))
($code->closure x)))
($pcb-set! set-code-byte!
(lambda (x i b)
(unless (code? x) (error 'set-code-byte! "~s is not a code" x))
(unless (and (fixnum? i) ($fx>= i 0))
(error 'set-code-byte! "~s is not a valid index" i))
(unless (and (fixnum? b) ($fx>= b 0) ($fx<= b 255))
(error 'set-code-byte! "~s is not a valid byte" b))
(unless ($fx< i ($code-instr-size x))
(error 'set-code-byte! "~s is out of range for a code of size ~s"
i
($code-instr-size x)))
($set-code-byte! x i b)))
($pcb-set! set-code-word!
(lambda (x i w)
(unless (code? x) (error 'set-code-word! "~s is not a code" x))
(unless (and (fixnum? i) ($fx>= i 0))
(error 'set-code-word! "~s is not a valid index" i))
(unless (and ($fx< i ($code-instr-size x))
($fx< ($fx+ i 3) ($code-instr-size x)))
(error 'set-code-word! "~s is out of range for a code of size ~s"
i
($code-instr-size x)))
($set-code-word! x i w)))
($pcb-set! set-code-object!
(lambda (code object code-offset reloc-index)
(unless (code? code)
(error 'set-code-object! "~s is not a code" code))
(unless (and (fixnum? code-offset)
($fx> code-offset 0)
($fx< code-offset ($code-instr-size code))
($fx< ($fx+ code-offset 3) ($code-instr-size code)))
(error 'set-code-object! "~s is not a valid code offset" code-offset))
(unless (and (fixnum? reloc-index)
($fx>= reloc-index 0)
($fx< reloc-index ($code-reloc-size code)))
(error 'set-code-object! "~s is not a valid reloc index" reloc-index))
($set-code-object! code object code-offset reloc-index)))
($pcb-set! set-code-object+offset!
(lambda (code object code-offset object-offset reloc-index)
(unless (code? code)
(error 'set-code-object+offset! "~s is not a code" code))
(unless (and (fixnum? code-offset)
($fx> code-offset 0)
($fx< code-offset ($code-instr-size code))
($fx< ($fx+ code-offset 3) ($code-instr-size code)))
(error 'set-code-object+offset!
"~s is not a valid code offset" code-offset))
(unless (and (fixnum? reloc-index)
($fx>= reloc-index 0)
($fx< reloc-index ($fx- ($code-reloc-size code) 1)))
(error 'set-code-object+offset!
"~s is not a valid reloc index" reloc-index))
($set-code-object+offset! code object
code-offset object-offset reloc-index)))
($pcb-set! set-code-object+offset/rel!
(lambda (code object code-offset object-offset reloc-index)
(unless (code? code)
(error 'set-code-object+offset/rel! "~s is not a code" code))
(unless (and (fixnum? code-offset)
($fx> code-offset 0)
($fx< code-offset ($code-instr-size code))
($fx< ($fx+ code-offset 3) ($code-instr-size code)))
(error 'set-code-object+offset/rel!
"~s is not a valid code offset" code-offset))
(unless (and (fixnum? reloc-index)
($fx>= reloc-index 0)
($fx< reloc-index ($fx- ($code-reloc-size code) 1)))
(error 'set-code-object+offset/rel!
"~s is not a valid reloc index" reloc-index))
($set-code-object+offset/rel! code object
code-offset object-offset reloc-index)))
($pcb-set! set-code-object/reloc/relative!
(lambda args (error 'set-code-object/reloc/relative! "not yet")))

View File

@ -30,6 +30,7 @@
(with-error-handler
(lambda args
(reset-input-port! (console-input-port))
(display "repl catch\n" (console-output-port))
(apply print-error args)
(k (void)))
(lambda ()
@ -51,22 +52,22 @@
v*))))]))))))
(wait eval escape-k)))
($pcb-set! new-cafe
(lambda args
(let ([eval
(if (null? args)
(current-eval)
(if (null? (cdr args))
(let ([f (car args)])
(if (procedure? f)
f
(error 'new-cafe "not a procedure ~s" f)))
(error 'new-cafe "too many arguments")))])
(dynamic-wind
(lambda () (set! eval-depth (fxadd1 eval-depth)))
(lambda ()
(call/cc
(lambda (k)
(wait eval k))))
(lambda () (set! eval-depth (fxsub1 eval-depth))))))))
(define new-cafe
(lambda (eval)
(dynamic-wind
(lambda () (set! eval-depth (fxadd1 eval-depth)))
(lambda ()
(call/cc
(lambda (k)
(wait eval k))))
(lambda () (set! eval-depth (fxsub1 eval-depth))))))
(primitive-set! 'new-cafe
(case-lambda
[() (new-cafe (current-eval))]
[(p)
(unless (procedure? p)
(error 'new-cafe "~s is not a procedure" p))
(new-cafe p)]))
)

Binary file not shown.

View File

@ -1,23 +0,0 @@
;($pcb-set! do-overflow
; (lambda ()
; ($do-overflow 4096)))
($pcb-set! do-overflow
(lambda ()
(foreign-call "S_collect" 4096)
(void)))
($pcb-set! collect
(lambda ()
(do-overflow)))
($pcb-set! do-overflow-with-byte-count
(lambda (n)
(foreign-call "S_collect" n)
(void)))
($pcb-set! do-stack-overflow
(lambda ()
(foreign-call "S_stack_overflow")))

Binary file not shown.

View File

@ -60,14 +60,28 @@
(unwind* winders tail)
(rewind* new tail))))
;;; (define call/cc
;;; (lambda (f)
;;; (primitive-call/cc
;;; (lambda (k)
;;; (let ([save winders])
;;; (f (lambda v*
;;; (unless (eq? save winders) (do-wind save))
;;; (apply k v*))))))))
(define call/cc
(lambda (f)
(primitive-call/cc
(lambda (k)
(let ([save winders])
(f (lambda v*
(unless (eq? save winders) (do-wind save))
(apply k v*))))))))
(f (case-lambda
[(v) (unless (eq? save winders) (do-wind save)) (k v)]
[() (unless (eq? save winders) (do-wind save)) (k)]
[(v1 v2 . v*)
(unless (eq? save winders) (do-wind save))
(apply k v1 v2 v*)])))))))
;;; (define dynamic-wind
;;; (lambda (in body out)
@ -78,18 +92,36 @@
;;; (out)
;;; v)))
;;; (define dynamic-wind
;;; (lambda (in body out)
;;; (in)
;;; (set! winders (cons (cons in out) winders))
;;; (call-with-values
;;; body
;;; (lambda v*
;;; (set! winders (cdr winders))
;;; (out)
;;; (apply values v*)))))
(define dynamic-wind
(lambda (in body out)
(in)
(set! winders (cons (cons in out) winders))
(call-with-values
body
(lambda v*
(set! winders (cdr winders))
(out)
(apply values v*)))))
(case-lambda
[(v) (set! winders (cdr winders)) (out) v]
[() (set! winders (cdr winders)) (out) (values)]
[(v1 v2 . v*)
(set! winders (cdr winders))
(out)
(apply values v1 v2 v*)]))))
($pcb-set! call/cf call-with-current-frame)
($pcb-set! call/cc call/cc)
($pcb-set! dynamic-wind dynamic-wind))
(primitive-set! 'call/cf call-with-current-frame)
(primitive-set! 'call/cc call/cc)
(primitive-set! 'dynamic-wind dynamic-wind)
;($install-underflow-handler)
(void))

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,6 @@
;;; 6.1: case-lambda
;;;
;;; Extended: cond case
;;;
@ -19,11 +21,11 @@
;;; | <gensym>
;;; | (<gensym> . <FML>)
;;; <prim> ::= void | memv | top-level-value | set-top-level-value!
;;; | $pcb-set! | foreign-call | $apply
;;; | primitive-set! '| foreign-call | $apply
;;;
;;;
;;; Handled keywords:
;;; Core: lambda set! if quote begin define
;;; Core: case-lambda lambda set! if quote begin define
;;; Extended: let let* letrec letrec* when unless or and cond case
;;; define-record record-case
@ -40,9 +42,6 @@
(lambda (x val)
(list 'set-top-level-value!
(build-constant x) val)))
(define build-pcb-set!
(lambda (x val)
(list '$pcb-set! x val)))
(define build-foreign-call
(lambda (name rand*)
(cons 'foreign-call
@ -92,7 +91,10 @@
(list 'if test conseq altern)))
(define build-function
(lambda (fml* body)
(list 'lambda fml* body)))
(build-case-lambda (list (list fml* body)))))
(define build-case-lambda
(lambda (cases)
(cons 'case-lambda cases)))
(define build-assignments
(lambda (lhs* rhs* body)
(cond
@ -372,14 +374,21 @@
;;;
(define E-lambda
(lambda (d env x)
(unless (fx>= (length d) 2) (syntax-error x))
(build-case-lambda
(list ((lambda-clause env x) d)))))
(define (lambda-clause env x)
(lambda (d)
(unless (and (list? d) (fx>= (length d) 2)) (syntax-error x))
(let ([fml* (car d)] [body* (cdr d)])
(verify-fml* fml* x)
(let ([nfml* (gen-fml* fml*)])
(let ([env (extend-env-fml* fml* nfml* env)])
(build-function
nfml*
(E-internal body* env x)))))))
(list nfml* (E-internal body* env x)))))))
(define E-case-lambda
(lambda (d env x)
(unless (fx>= (length d) 1) (syntax-error x))
(build-case-lambda
(map (lambda-clause env x) d))))
(define verify-fml*
(lambda (fml* x)
(let ([g (gensym)])
@ -841,13 +850,6 @@
(build-lexical-reference v)
(build-constant x))))]))))
;;;
(define E-pcb-set!
(lambda (d env x)
(unless (fx= (length d) 2) (syntax-error x))
(let ([name (car d)] [val (cadr d)])
(unless (symbol? name) (syntax-error x))
(build-pcb-set! (build-constant name) (E val env)))))
;;;
(define E-foreign-call
(lambda (d env x)
(unless (fx>= (length d) 1) (syntax-error x))
@ -902,6 +904,7 @@
[(eq? a 'set!) (E-set! d env x)]
[(eq? a 'begin) (E-begin d env x)]
[(eq? a 'lambda) (E-lambda d env x)]
[(eq? a 'case-lambda) (E-case-lambda d env x)]
[(eq? a 'let) (E-let d env x)]
[(eq? a 'letrec) (E-letrec d env x)]
[(eq? a 'let*) (E-let* d env x)]
@ -918,7 +921,6 @@
[(eq? a 'record-case) (E-record-case d env x)]
[(eq? a 'foreign-call) (E-foreign-call d env x)]
[(eq? a '|#primitive|) (E-primref d env x)]
[(eq? a '$pcb-set!) (E-pcb-set! d env x)]
[(eq? a '$apply) (E-apply d env x)]
[else (syntax-error x)])]
[else
@ -1047,9 +1049,9 @@
(E* d empty-env))]))]
[else (syntax-error x)])))
;;;
($pcb-set! core-expand E-top)
(primitive-set! 'core-expand E-top)
;;;
($pcb-set! current-expand
(primitive-set! 'current-expand
(make-parameter
core-expand
(lambda (x)
@ -1057,7 +1059,7 @@
(error 'current-expand "~s is not a procedure" x))
x)))
;;;
($pcb-set! expand
(primitive-set! 'expand
(lambda (x)
((current-expand) x)))
;;;
@ -1065,7 +1067,7 @@
(lambda (x)
(putprop x *keyword* x))
'(lambda set! let let* letrec letrec* if quote when unless set! begin
define or and cond case $pcb-set! foreign-call $apply |#primitive|
case-lambda define or and cond case foreign-call $apply |#primitive|