diff options
Diffstat (limited to 'gs/src/imain.c')
-rw-r--r-- | gs/src/imain.c | 252 |
1 files changed, 92 insertions, 160 deletions
diff --git a/gs/src/imain.c b/gs/src/imain.c index efa4ce113..227ec3755 100644 --- a/gs/src/imain.c +++ b/gs/src/imain.c @@ -18,16 +18,6 @@ /* Common support for interpreter front ends */ #include "memory_.h" #include "string_.h" -/* Capture stdin/out/err before gs.h redefines them. */ -#include <stdio.h> -#include <stdlib.h> -private void -set_stdfiles(FILE * stdfiles[3]) -{ - stdfiles[0] = stdin; - stdfiles[1] = stdout; - stdfiles[2] = stderr; -} #include "ghost.h" #include "gp.h" #include "gscdefs.h" /* for gs_init_file */ @@ -58,27 +48,43 @@ set_stdfiles(FILE * stdfiles[3]) #include "isave.h" /* for prototypes */ #include "interp.h" #include "ivmspace.h" -#include "idisp.h" /* for setting display device callback */ #include "iplugin.h" /* ------ Exported data ------ */ -/* Define the default instance of the interpreter. */ -/* Currently, this is the *only possible* instance, because most of */ -/* the places that need to take an explicit instance argument don't. */ -private gs_main_instance the_gs_main_instance; -gs_main_instance * -gs_main_instance_default(void) +/** using backpointers retrieve minst from any memory pointer + * + */ +gs_main_instance* +get_minst_from_memory(const gs_memory_t *mem) { - /* Determine whether the instance has been initialized. */ - if (the_gs_main_instance.memory_chunk_size == 0) - the_gs_main_instance = gs_main_instance_init_values; - return &the_gs_main_instance; +#ifdef PSI_INCLUDED + extern gs_main_instance *ps_impl_get_minst( const gs_memory_t *mem ); + return ps_impl_get_minst(mem); +#else + return (gs_main_instance*)mem->gs_lib_ctx->top_of_system; +#endif } -/* Define the interpreter's name table. We'll move it somewhere better */ -/* eventually.... */ -name_table *the_gs_name_table; +/** construct main instance caller needs to retain */ +gs_main_instance * +gs_main_alloc_instance(gs_memory_t *mem) +{ + gs_main_instance *minst = 0; + if (mem) { + minst = (gs_main_instance *) gs_alloc_bytes_immovable(mem, + sizeof(gs_main_instance), + "init_main_instance"); + memcpy(minst, &gs_main_instance_init_values, sizeof(gs_main_instance_init_values)); + minst->heap = mem; + +# ifndef PSI_INCLUDED + mem->gs_lib_ctx->top_of_system = minst; + /* else top of system is pl_universe */ +# endif + } + return minst; +} /* ------ Forward references ------ */ @@ -88,45 +94,38 @@ private void print_resource_usage(const gs_main_instance *, /* ------ Initialization ------ */ -/* Save the real stdio files. */ -void -gs_get_real_stdio(FILE * stdfiles[3]) -{ - set_stdfiles(stdfiles); -} - /* Initialization to be done before anything else. */ int gs_main_init0(gs_main_instance * minst, FILE * in, FILE * out, FILE * err, int max_lib_paths) { - gs_memory_t *heap; ref *paths; - /* Set our versions of stdin/out/err. */ - gs_stdin = minst->fstdin = in; - gs_stdout = minst->fstdout = out; - gs_stderr = minst->fstderr = err; /* Do platform-dependent initialization. */ /* We have to do this as the very first thing, */ /* because it detects attempts to run 80N86 executables (N>0) */ /* on incompatible processors. */ gp_init(); + + /* Initialize the imager. */ +# ifndef PSI_INCLUDED + /* Reset debugging flags */ + memset(gs_debug, 0, 128); + gs_log_errors = 0; /* gs_debug['#'] = 0 */ +# else + /* plmain settings remain in effect */ +# endif gp_get_usertime(minst->base_time); - /* Initialize the imager. */ - heap = gs_lib_init0(gs_stdout); - if (heap == 0) - return_error(e_VMerror); - minst->heap = heap; + /* Initialize the file search paths. */ - paths = (ref *) gs_alloc_byte_array(heap, max_lib_paths, sizeof(ref), + paths = (ref *) gs_alloc_byte_array(minst->heap, max_lib_paths, sizeof(ref), "lib_path array"); if (paths == 0) { - gs_lib_finit(1, e_VMerror); + gs_lib_finit(1, e_VMerror, minst->heap); return_error(e_VMerror); } make_array(&minst->lib_path.container, avm_foreign, max_lib_paths, - (ref *) gs_alloc_byte_array(heap, max_lib_paths, sizeof(ref), + (ref *) gs_alloc_byte_array(minst->heap, max_lib_paths, sizeof(ref), "lib_path array")); make_array(&minst->lib_path.list, avm_foreign | a_readonly, 0, minst->lib_path.container.value.refs); @@ -145,7 +144,7 @@ gs_main_init1(gs_main_instance * minst) if (minst->init_done < 1) { gs_dual_memory_t idmem; int code = - ialloc_init(&idmem, (gs_raw_memory_t *)&gs_memory_default, + ialloc_init(&idmem, minst->heap, minst->memory_chunk_size, gs_have_level2()); if (code < 0) @@ -161,9 +160,9 @@ gs_main_init1(gs_main_instance * minst) if (nt == 0) return_error(e_VMerror); - the_gs_name_table = nt; + mem->gs_lib_ctx->gs_name_table = nt; code = gs_register_struct_root(mem, NULL, - (void **)&the_gs_name_table, + (void **)&mem->gs_lib_ctx->gs_name_table, "the_gs_name_table"); if (code < 0) return code; @@ -207,6 +206,9 @@ gs_main_interpret(gs_main_instance *minst, ref * pref, int user_errors, ref refpop; int code; + /* set interpreter pointer to lib_path */ + minst->i_ctx_p->lib_path = &minst->lib_path; + code = gs_interpret(&minst->i_ctx_p, pref, user_errors, pexit_code, perror_object); while ((code == e_NeedStdin) || (code == e_NeedStdout) || @@ -226,7 +228,7 @@ gs_main_interpret(gs_main_instance *minst, ref * pref, int user_errors, int count = esp[0].tas.rsize; int rcode = 0; if (str != NULL) - rcode = gs_main_outwrite(minst, str, count); + rcode = outwrite(imemory, str, count); if (rcode < 0) return_error(e_ioerror); } @@ -248,7 +250,7 @@ gs_main_interpret(gs_main_instance *minst, ref * pref, int user_errors, int count = esp[0].tas.rsize; int rcode = 0; if (str != NULL) - rcode = gs_main_errwrite(minst, str, count); + rcode = errwrite(str, count); if (rcode < 0) return_error(e_ioerror); } @@ -266,12 +268,14 @@ gs_main_interpret(gs_main_instance *minst, ref * pref, int user_errors, * esp[-1] = file, stdin stream * We read from stdin then pop these 2 items. */ - if (minst->stdin_fn) - count = (*minst->stdin_fn)(minst->caller_handle, - minst->stdin_buf, count); + if (minst->heap->gs_lib_ctx->stdin_fn) + count = (*minst->heap->gs_lib_ctx->stdin_fn) + (minst->heap->gs_lib_ctx->caller_handle, + minst->stdin_buf, count); else count = gp_stdin_read(minst->stdin_buf, count, - minst->stdin_is_interactive, minst->fstdin); + minst->heap->gs_lib_ctx->stdin_is_interactive, + minst->heap->gs_lib_ctx->fstdin); if (count < 0) return_error(e_ioerror); @@ -348,8 +352,12 @@ gs_main_init2(gs_main_instance * minst) return code; minst->init_done = 2; i_ctx_p = minst->i_ctx_p; /* init file may change it */ + /* NB this is to be done with device parameters + * both minst->display and display_set_callback() are going away + */ if (minst->display) code = display_set_callback(minst, minst->display); + if (code < 0) return code; } @@ -465,10 +473,11 @@ gs_main_lib_open(gs_main_instance * minst, const char *file_name, ref * pfile) byte fn[maxfn]; uint len; - return lib_file_open(NULL /* Don't check permissions here, because permlist - isn't ready running init files. */ - , file_name, strlen(file_name), fn, maxfn, - &len, pfile, imemory); + return lib_file_open( &minst->lib_path, + NULL /* Don't check permissions here, because permlist + isn't ready running init files. */ + , file_name, strlen(file_name), fn, maxfn, + &len, pfile, imemory); } /* Open and execute a file. */ @@ -728,7 +737,7 @@ gs_pop_string(gs_main_instance * minst, gs_string * result) return code; switch (r_type(&vref)) { case t_name: - name_string_ref(&vref, &vref); + name_string_ref(minst->heap, &vref, &vref); code = 1; goto rstr; case t_string: @@ -771,7 +780,7 @@ private char *gs_main_tempnames(gs_main_instance *minst) /* get lengths of temporary filenames */ idict = dict_first(tempfiles); while ((idict = dict_next(tempfiles, idict, &keyval[0])) >= 0) { - if (obj_string_data(&keyval[0], &data, &size) >= 0) + if (obj_string_data(minst->heap, &keyval[0], &data, &size) >= 0) len += size + 1; } if (len != 0) @@ -782,7 +791,7 @@ private char *gs_main_tempnames(gs_main_instance *minst) idict = dict_first(tempfiles); i = 0; while ((idict = dict_next(tempfiles, idict, &keyval[0])) >= 0) { - if (obj_string_data(&keyval[0], &data, &size) >= 0) { + if (obj_string_data(minst->heap, &keyval[0], &data, &size) >= 0) { memcpy(tempnames+i, (const char *)data, size); i+= size; tempnames[i++] = '\0'; @@ -801,6 +810,10 @@ gs_main_finit(gs_main_instance * minst, int exit_status, int code) int exit_code; ref error_object; char *tempnames; + + /* NB: need to free gs_name_table + */ + /* * Previous versions of this code closed the devices in the * device list here. Since these devices are now prototypes, @@ -851,19 +864,20 @@ gs_main_finit(gs_main_instance * minst, int exit_status, int code) /* Do the equivalent of a restore "past the bottom". */ /* This will release all memory, close all open files, etc. */ if (minst->init_done >= 1) { - gs_raw_memory_t *mem_raw = i_ctx_p->memory.current->parent; + gs_memory_t *mem_raw = i_ctx_p->memory.current->non_gc_memory; i_plugin_holder *h = i_ctx_p->plugin_list; alloc_restore_all(idmemory); i_plugin_finit(mem_raw, h); } /* clean up redirected stdout */ - if (minst->fstdout2 && (minst->fstdout2 != minst->fstdout) - && (minst->fstdout2 != minst->fstderr)) { - fclose(minst->fstdout2); - minst->fstdout2 = (FILE *)NULL; + if (minst->heap->gs_lib_ctx->fstdout2 + && (minst->heap->gs_lib_ctx->fstdout2 != minst->heap->gs_lib_ctx->fstdout) + && (minst->heap->gs_lib_ctx->fstdout2 != minst->heap->gs_lib_ctx->fstderr)) { + fclose(minst->heap->gs_lib_ctx->fstdout2); + minst->heap->gs_lib_ctx->fstdout2 = (FILE *)NULL; } - minst->stdout_is_redirected = 0; - minst->stdout_to_stderr = 0; + minst->heap->gs_lib_ctx->stdout_is_redirected = 0; + minst->heap->gs_lib_ctx->stdout_to_stderr = 0; /* remove any temporary files, after ghostscript has closed files */ if (tempnames) { char *p = tempnames; @@ -873,23 +887,23 @@ gs_main_finit(gs_main_instance * minst, int exit_status, int code) } free(tempnames); } - gs_lib_finit(exit_status, code); + gs_lib_finit(exit_status, code, minst->heap); return exit_status; } int -gs_to_exit_with_code(int exit_status, int code) +gs_to_exit_with_code(const gs_memory_t *mem, int exit_status, int code) { - return gs_finit(exit_status, code); + return gs_main_finit(get_minst_from_memory(mem), exit_status, code); } int -gs_to_exit(int exit_status) +gs_to_exit(const gs_memory_t *mem, int exit_status) { - return gs_to_exit_with_code(exit_status, 0); + return gs_to_exit_with_code(mem, exit_status, 0); } void -gs_abort(void) +gs_abort(const gs_memory_t *mem) { - gs_to_exit(1); + gs_to_exit(mem, 1); /* it's fatal calling OS independent exit() */ gp_do_exit(1); } @@ -943,93 +957,11 @@ gs_main_dump_stack(gs_main_instance *minst, int code, ref * perror_object) dprintf1("\nUnexpected interpreter error %d.\n", code); if (perror_object != 0) { dputs("Error object: "); - debug_print_ref(perror_object); + debug_print_ref(minst->heap, perror_object); dputc('\n'); } - debug_dump_stack(&o_stack, "Operand stack"); - debug_dump_stack(&e_stack, "Execution stack"); - debug_dump_stack(&d_stack, "Dictionary stack"); -} -/* Backward compatibility */ -void -gs_debug_dump_stack(int code, ref * perror_object) -{ - gs_main_dump_stack(gs_main_instance_default(), code, perror_object); -} - - -/* Provide a single point for all "C" stdout and stderr. - * Eventually these will always be referenced through an instance structure. - * We don't know which instance is running (and currently only one - * instance is possible) so use the default instance. - */ - -int -gs_main_outwrite(gs_main_instance *minst, const char *str, int len) -{ - int code; - FILE *fout; - if (len == 0) - return 0; - if (minst->stdout_is_redirected) { - if (minst->stdout_to_stderr) - return gs_main_errwrite(minst, str, len); - fout = minst->fstdout2; - } - else if (minst->stdout_fn) { - return (*minst->stdout_fn)(minst->caller_handle, str, len); - } - else { - fout = minst->fstdout; - } - code = fwrite(str, 1, len, fout); - fflush(fout); - return code; + debug_dump_stack(minst->heap, &o_stack, "Operand stack"); + debug_dump_stack(minst->heap, &e_stack, "Execution stack"); + debug_dump_stack(minst->heap, &d_stack, "Dictionary stack"); } -int -gs_main_errwrite(gs_main_instance *minst, const char *str, int len) -{ - int code; - if (len == 0) - return 0; - if (minst->stderr_fn) - return (*minst->stderr_fn)(minst->caller_handle, str, len); - code = fwrite(str, 1, len, minst->fstderr); - fflush(minst->fstderr); - return code; -} - -int outwrite(const char *str, int len) -{ - return gs_main_outwrite(gs_main_instance_default(), str, len); -} - -int errwrite(const char *str, int len) -{ - return gs_main_errwrite(gs_main_instance_default(), str, len); -} - -void outflush(void) -{ - gs_main_instance * minst = gs_main_instance_default(); - if (minst->stdout_is_redirected) { - if (minst->stdout_to_stderr) { - if (!minst->stderr_fn) - fflush(minst->fstderr); - } - else - fflush(minst->fstdout2); - } - else if (!minst->stdout_fn) - fflush(minst->fstdout); -} - -void errflush(void) -{ - gs_main_instance * minst = gs_main_instance_default(); - if (!minst->stderr_fn) - fflush(minst->fstderr); -} - - |