mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-19 05:39:18 +02:00
allow loading images from offsets
This commit is contained in:
parent
524179388d
commit
eed963381c
3 changed files with 27 additions and 22 deletions
33
gc_heap.c
33
gc_heap.c
|
@ -574,21 +574,27 @@ char* sexp_load_image_err() {
|
||||||
return gc_heap_err_str;
|
return gc_heap_err_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_load_image (const char* filename, sexp_uint_t heap_free_size, sexp_uint_t heap_max_size) {
|
sexp sexp_load_image (const char* filename, off_t offset, sexp_uint_t heap_free_size, sexp_uint_t heap_max_size) {
|
||||||
sexp res = NULL;
|
struct load_image_state state;
|
||||||
sexp ctx = NULL;
|
struct sexp_image_header_t header;
|
||||||
|
FILE *fp;
|
||||||
|
int i;
|
||||||
|
sexp res = NULL, ctx = NULL, base, *ctx_globals, *ctx_types;
|
||||||
|
|
||||||
gc_heap_err_str[0] = 0;
|
gc_heap_err_str[0] = 0;
|
||||||
|
|
||||||
struct load_image_state state;
|
|
||||||
memset(&state, 0, sizeof(struct load_image_state));
|
memset(&state, 0, sizeof(struct load_image_state));
|
||||||
|
|
||||||
FILE *fp = fopen(filename, "rb");
|
fp = fopen(filename, "rb");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
snprintf(gc_heap_err_str, ERR_STR_SIZE, "couldn't open image file for reading: %s\n", filename);
|
snprintf(gc_heap_err_str, ERR_STR_SIZE, "couldn't open image file for reading: %s\n", filename);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (offset > 0 && fseek(fp, offset, SEEK_SET) < 0) {
|
||||||
|
snprintf(gc_heap_err_str, ERR_STR_SIZE, "couldn't seek to image offset: %s -> %lld: %s\n", filename, offset, strerror(errno));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
struct sexp_image_header_t header;
|
|
||||||
if (!load_image_header(fp, &header)) { goto done; }
|
if (!load_image_header(fp, &header)) { goto done; }
|
||||||
|
|
||||||
state.heap = sexp_gc_packed_heap_make(header.size, heap_free_size);
|
state.heap = sexp_gc_packed_heap_make(header.size, heap_free_size);
|
||||||
|
@ -596,7 +602,7 @@ sexp sexp_load_image (const char* filename, sexp_uint_t heap_free_size, sexp_uin
|
||||||
snprintf(gc_heap_err_str, ERR_STR_SIZE, "couldn't malloc heap\n");
|
snprintf(gc_heap_err_str, ERR_STR_SIZE, "couldn't malloc heap\n");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
sexp base = sexp_heap_first_block(state.heap);
|
base = sexp_heap_first_block(state.heap);
|
||||||
|
|
||||||
if (fread(base, 1, header.size, fp) != header.size) {
|
if (fread(base, 1, header.size, fp) != header.size) {
|
||||||
snprintf(gc_heap_err_str, ERR_STR_SIZE, "error reading image\n");
|
snprintf(gc_heap_err_str, ERR_STR_SIZE, "error reading image\n");
|
||||||
|
@ -614,24 +620,23 @@ sexp sexp_load_image (const char* filename, sexp_uint_t heap_free_size, sexp_uin
|
||||||
copy of the type array pointers with correct offsets is applied is created outside
|
copy of the type array pointers with correct offsets is applied is created outside
|
||||||
of the new heap to be used with the pointer adjustment process.
|
of the new heap to be used with the pointer adjustment process.
|
||||||
*/
|
*/
|
||||||
sexp* ctx_globals = sexp_vector_data((sexp)((unsigned char*)sexp_context_globals(ctx) + state.offset));
|
ctx_globals = sexp_vector_data((sexp)((unsigned char*)sexp_context_globals(ctx) + state.offset));
|
||||||
sexp* ctx_types = sexp_vector_data((sexp)((unsigned char*)(ctx_globals[SEXP_G_TYPES]) + state.offset));
|
ctx_types = sexp_vector_data((sexp)((unsigned char*)(ctx_globals[SEXP_G_TYPES]) + state.offset));
|
||||||
state.types_cnt = sexp_unbox_fixnum(ctx_globals[SEXP_G_NUM_TYPES]);
|
state.types_cnt = sexp_unbox_fixnum(ctx_globals[SEXP_G_NUM_TYPES]);
|
||||||
state.types = malloc(sizeof(sexp) * state.types_cnt);
|
state.types = malloc(sizeof(sexp) * state.types_cnt);
|
||||||
if (!state.types) goto done;
|
if (!state.types) goto done;
|
||||||
int i;
|
|
||||||
for (i = 0; i < state.types_cnt; i++) {
|
for (i = 0; i < state.types_cnt; i++) {
|
||||||
state.types[i] = (sexp)((unsigned char *)ctx_types[i] + state.offset);
|
state.types[i] = (sexp)((unsigned char *)ctx_types[i] + state.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sexp_gc_heap_walk(ctx, sexp_context_heap(ctx), state.types, state.types_cnt,
|
if (sexp_gc_heap_walk(ctx, sexp_context_heap(ctx), state.types, state.types_cnt,
|
||||||
&state, NULL, NULL, load_image_callback_p1) != SEXP_TRUE) {
|
&state, NULL, NULL, load_image_callback_p1) != SEXP_TRUE)
|
||||||
goto done; }
|
goto done;
|
||||||
|
|
||||||
/* Second pass to fix code references */
|
/* Second pass to fix code references */
|
||||||
if (sexp_gc_heap_walk(ctx, sexp_context_heap(ctx), state.types, state.types_cnt,
|
if (sexp_gc_heap_walk(ctx, sexp_context_heap(ctx), state.types, state.types_cnt,
|
||||||
&state, NULL, NULL, load_image_callback_p2) != SEXP_TRUE) {
|
&state, NULL, NULL, load_image_callback_p2) != SEXP_TRUE)
|
||||||
goto done; }
|
goto done;
|
||||||
|
|
||||||
if (heap_max_size > SEXP_INITIAL_HEAP_SIZE) {
|
if (heap_max_size > SEXP_INITIAL_HEAP_SIZE) {
|
||||||
sexp_context_heap(ctx)->max_size = heap_max_size;
|
sexp_context_heap(ctx)->max_size = heap_max_size;
|
||||||
|
|
|
@ -82,7 +82,7 @@ SEXP_API sexp sexp_save_image (sexp ctx, const char* filename);
|
||||||
to provide a description of the error encountered. An sexp exception cannot be
|
to provide a description of the error encountered. An sexp exception cannot be
|
||||||
returned because there is not a valid context in which to put the exception.
|
returned because there is not a valid context in which to put the exception.
|
||||||
*/
|
*/
|
||||||
SEXP_API sexp sexp_load_image (const char* filename, sexp_uint_t heap_free_size, sexp_uint_t heap_max_size);
|
SEXP_API sexp sexp_load_image (const char* filename, off_t offset, sexp_uint_t heap_free_size, sexp_uint_t heap_max_size);
|
||||||
|
|
||||||
|
|
||||||
/* In the case that sexp_load_image() returns NULL, this function will return
|
/* In the case that sexp_load_image() returns NULL, this function will return
|
||||||
|
|
2
main.c
2
main.c
|
@ -409,7 +409,7 @@ sexp run_main (int argc, char **argv) {
|
||||||
fprintf(stderr, "-:i <file>: image files must be loaded first\n");
|
fprintf(stderr, "-:i <file>: image files must be loaded first\n");
|
||||||
exit_failure();
|
exit_failure();
|
||||||
}
|
}
|
||||||
ctx = sexp_load_image(arg, heap_size, heap_max_size);
|
ctx = sexp_load_image(arg, 0, heap_size, heap_max_size);
|
||||||
if (!ctx || !sexp_contextp(ctx)) {
|
if (!ctx || !sexp_contextp(ctx)) {
|
||||||
fprintf(stderr, "-:i <file>: couldn't open file for reading: %s\n", arg);
|
fprintf(stderr, "-:i <file>: couldn't open file for reading: %s\n", arg);
|
||||||
fprintf(stderr, " %s\n", sexp_load_image_err());
|
fprintf(stderr, " %s\n", sexp_load_image_err());
|
||||||
|
|
Loading…
Add table
Reference in a new issue