2004-07-16 02:26:21 -04:00
|
|
|
#include "factor.h"
|
|
|
|
|
|
|
|
void fixup(CELL* cell)
|
|
|
|
{
|
2004-09-08 02:31:03 -04:00
|
|
|
if(TAG(*cell) != FIXNUM_TYPE && *cell != F)
|
2004-08-31 20:31:16 -04:00
|
|
|
*cell += (active.base - relocation_base);
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void relocate_object()
|
|
|
|
{
|
|
|
|
switch(untag_header(get(relocating)))
|
|
|
|
{
|
2004-07-27 23:29:37 -04:00
|
|
|
case WORD_TYPE:
|
|
|
|
fixup_word((WORD*)relocating);
|
|
|
|
break;
|
2004-07-16 02:26:21 -04:00
|
|
|
case ARRAY_TYPE:
|
|
|
|
fixup_array((ARRAY*)relocating);
|
|
|
|
break;
|
|
|
|
case VECTOR_TYPE:
|
|
|
|
fixup_vector((VECTOR*)relocating);
|
|
|
|
break;
|
2004-08-29 23:30:54 -04:00
|
|
|
case STRING_TYPE:
|
|
|
|
hash_string((STRING*)relocating);
|
|
|
|
break;
|
2004-07-16 02:26:21 -04:00
|
|
|
case SBUF_TYPE:
|
|
|
|
fixup_sbuf((SBUF*)relocating);
|
|
|
|
break;
|
2004-08-12 17:36:36 -04:00
|
|
|
case PORT_TYPE:
|
|
|
|
fixup_port((PORT*)relocating);
|
2004-08-24 23:46:55 -04:00
|
|
|
break;
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void relocate_next()
|
|
|
|
{
|
2004-09-08 02:31:03 -04:00
|
|
|
CELL size = CELLS;
|
|
|
|
|
2004-07-16 02:26:21 -04:00
|
|
|
switch(TAG(get(relocating)))
|
|
|
|
{
|
|
|
|
case HEADER_TYPE:
|
2004-09-08 02:31:03 -04:00
|
|
|
size = untagged_object_size(relocating);
|
2004-07-16 02:26:21 -04:00
|
|
|
relocate_object();
|
|
|
|
break;
|
2004-09-08 02:31:03 -04:00
|
|
|
case OBJECT_TYPE:
|
|
|
|
if(get(relocating) == F)
|
|
|
|
break;
|
|
|
|
/* fall thru */
|
2004-07-16 02:26:21 -04:00
|
|
|
default:
|
|
|
|
fixup((CELL*)relocating);
|
2004-09-08 02:31:03 -04:00
|
|
|
break;
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
2004-09-08 02:31:03 -04:00
|
|
|
relocating += size;
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
2004-08-29 01:04:42 -04:00
|
|
|
void init_object(CELL* handle, CELL type)
|
|
|
|
{
|
|
|
|
if(untag_header(get(relocating)) != type)
|
|
|
|
fatal_error("init_object() failed",get(relocating));
|
|
|
|
*handle = tag_object((CELL*)relocating);
|
|
|
|
relocate_next();
|
|
|
|
}
|
|
|
|
|
2004-07-16 02:26:21 -04:00
|
|
|
void relocate(CELL r)
|
|
|
|
{
|
|
|
|
relocation_base = r;
|
|
|
|
|
2004-08-20 18:48:08 -04:00
|
|
|
fixup(&userenv[BOOT_ENV]);
|
|
|
|
fixup(&userenv[GLOBAL_ENV]);
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-08-31 20:31:16 -04:00
|
|
|
relocating = active.base;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-09-08 02:31:03 -04:00
|
|
|
/* The first object in the image must always T */
|
2004-08-29 01:04:42 -04:00
|
|
|
init_object(&T,T_TYPE);
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-08-29 01:04:42 -04:00
|
|
|
/* The next three must be bignum 0, 1, -1 */
|
|
|
|
init_object(&bignum_zero,BIGNUM_TYPE);
|
|
|
|
init_object(&bignum_pos_one,BIGNUM_TYPE);
|
|
|
|
init_object(&bignum_neg_one,BIGNUM_TYPE);
|
|
|
|
|
2004-07-16 02:26:21 -04:00
|
|
|
for(;;)
|
|
|
|
{
|
2004-08-31 20:31:16 -04:00
|
|
|
if(relocating >= active.here)
|
2004-07-16 02:26:21 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
relocate_next();
|
|
|
|
}
|
|
|
|
}
|