summaryrefslogtreecommitdiff
path: root/gs/psi/interp.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/psi/interp.c')
-rw-r--r--gs/psi/interp.c2018
1 files changed, 1009 insertions, 1009 deletions
diff --git a/gs/psi/interp.c b/gs/psi/interp.c
index ddfe3f7ae..44ae93212 100644
--- a/gs/psi/interp.c
+++ b/gs/psi/interp.c
@@ -16,8 +16,8 @@
#include "memory_.h"
#include "string_.h"
#include "ghost.h"
-#include "gsstruct.h" /* for iastruct.h */
-#include "gserrors.h" /* for gpcheck.h */
+#include "gsstruct.h" /* for iastruct.h */
+#include "gserrors.h" /* for gpcheck.h */
#include "stream.h"
#include "ierrors.h"
#include "estack.h"
@@ -26,24 +26,24 @@
#include "icontext.h"
#include "icremap.h"
#include "idebug.h"
-#include "igstate.h" /* for handling e_RemapColor */
+#include "igstate.h" /* for handling e_RemapColor */
#include "inamedef.h"
-#include "iname.h" /* for the_name_table */
+#include "iname.h" /* for the_name_table */
#include "interp.h"
#include "ipacked.h"
-#include "ostack.h" /* must precede iscan.h */
-#include "strimpl.h" /* for sfilter.h */
-#include "sfilter.h" /* for iscan.h */
+#include "ostack.h" /* must precede iscan.h */
+#include "strimpl.h" /* for sfilter.h */
+#include "sfilter.h" /* for iscan.h */
#include "iscan.h"
#include "iddict.h"
#include "isave.h"
#include "istack.h"
#include "itoken.h"
-#include "iutil.h" /* for array_get */
+#include "iutil.h" /* for array_get */
#include "ivmspace.h"
#include "iinit.h"
#include "dstack.h"
-#include "files.h" /* for file_check_read */
+#include "files.h" /* for file_check_read */
#include "oper.h"
#include "store.h"
#include "gpcheck.h"
@@ -86,16 +86,16 @@ call_operator(op_proc_t op_proc, i_ctx_t *i_ctx_p)
if_debug1('!', "[!]operator %s\n", op_get_name_string(op_proc));
# else
if_debug3('!', "[!][es=%d os=%d]operator %s\n",
- esp-i_ctx_p->exec_stack.stack.bot,
- osp-i_ctx_p->op_stack.stack.bot,
- op_get_name_string(op_proc));
+ esp-i_ctx_p->exec_stack.stack.bot,
+ osp-i_ctx_p->op_stack.stack.bot,
+ op_get_name_string(op_proc));
# endif
# endif
code = op_proc(i_ctx_p);
# if defined(DEBUG_TRACE_PS_OPERATORS) && defined(SHOW_STACK_DEPTHS)
if_debug2('!', "[!][es=%d os=%d]\n",
- esp-i_ctx_p->exec_stack.stack.bot,
- osp-i_ctx_p->op_stack.stack.bot);
+ esp-i_ctx_p->exec_stack.stack.bot,
+ osp-i_ctx_p->op_stack.stack.bot);
# endif
return code; /* A good place for a conditional breakpoint. */
}
@@ -109,10 +109,10 @@ struct stats_interp_s {
long top;
long lit, lit_array, exec_array, exec_operator, exec_name;
long x_add, x_def, x_dup, x_exch, x_if, x_ifelse,
- x_index, x_pop, x_roll, x_sub;
+ x_index, x_pop, x_roll, x_sub;
long find_name, name_lit, name_proc, name_oparray, name_operator;
long p_full, p_exec_operator, p_exec_oparray, p_exec_non_x_operator,
- p_integer, p_lit_name, p_exec_name;
+ p_integer, p_lit_name, p_exec_name;
long p_find_name, p_name_lit, p_name_proc;
} stats_interp;
# define INCR(v) (++(stats_interp.v))
@@ -156,7 +156,7 @@ static int zcurrentstackprotect(i_ctx_t *);
* and therefore pushes 16 values).
*/
#define MIN_BLOCK_OSTACK 16
-const int gs_interp_max_op_num_args = MIN_BLOCK_OSTACK; /* for iinit.c */
+const int gs_interp_max_op_num_args = MIN_BLOCK_OSTACK; /* for iinit.c */
/*
* Define the initial maximum size of the execution stack (MaxExecStack
@@ -235,7 +235,7 @@ typedef enum {
} special_op_types;
#define num_special_ops ((int)tx_next_op - tx_op)
-const int gs_interp_num_special_ops = num_special_ops; /* for iinit.c */
+const int gs_interp_num_special_ops = num_special_ops; /* for iinit.c */
const int tx_next_index = tx_next_op;
/*
@@ -279,16 +279,16 @@ const op_def interp2_op_defs[] = {
/* Initialize the interpreter. */
int
gs_interp_init(i_ctx_t **pi_ctx_p, const ref *psystem_dict,
- gs_dual_memory_t *dmem)
+ gs_dual_memory_t *dmem)
{
/* Create and initialize a context state. */
gs_context_state_t *pcst = 0;
int code = context_state_alloc(&pcst, psystem_dict, dmem);
if (code >= 0)
- code = context_state_load(pcst);
+ code = context_state_load(pcst);
if (code < 0)
- lprintf1("Fatal error %d in gs_interp_init!", code);
+ lprintf1("Fatal error %d in gs_interp_init!", code);
*pi_ctx_p = pcst;
return code;
}
@@ -300,51 +300,51 @@ int
gs_interp_alloc_stacks(gs_ref_memory_t *mem, gs_context_state_t * pcst)
{
gs_ref_memory_t *smem =
- (gs_ref_memory_t *)gs_memory_stable((gs_memory_t *)mem);
+ (gs_ref_memory_t *)gs_memory_stable((gs_memory_t *)mem);
ref stk;
#define REFS_SIZE_OSTACK OS_REFS_SIZE(MAX_OSTACK)
#define REFS_SIZE_ESTACK ES_REFS_SIZE(MAX_ESTACK)
#define REFS_SIZE_DSTACK DS_REFS_SIZE(MAX_DSTACK)
gs_alloc_ref_array(smem, &stk, 0,
- REFS_SIZE_OSTACK + REFS_SIZE_ESTACK +
- REFS_SIZE_DSTACK, "gs_interp_alloc_stacks");
+ REFS_SIZE_OSTACK + REFS_SIZE_ESTACK +
+ REFS_SIZE_DSTACK, "gs_interp_alloc_stacks");
{
- ref_stack_t *pos = &pcst->op_stack.stack;
-
- r_set_size(&stk, REFS_SIZE_OSTACK);
- ref_stack_init(pos, &stk, OS_GUARD_UNDER, OS_GUARD_OVER, NULL,
- smem, NULL);
- ref_stack_set_error_codes(pos, e_stackunderflow, e_stackoverflow);
- ref_stack_set_max_count(pos, MAX_OSTACK);
- stk.value.refs += REFS_SIZE_OSTACK;
+ ref_stack_t *pos = &pcst->op_stack.stack;
+
+ r_set_size(&stk, REFS_SIZE_OSTACK);
+ ref_stack_init(pos, &stk, OS_GUARD_UNDER, OS_GUARD_OVER, NULL,
+ smem, NULL);
+ ref_stack_set_error_codes(pos, e_stackunderflow, e_stackoverflow);
+ ref_stack_set_max_count(pos, MAX_OSTACK);
+ stk.value.refs += REFS_SIZE_OSTACK;
}
{
- ref_stack_t *pes = &pcst->exec_stack.stack;
- ref euop;
-
- r_set_size(&stk, REFS_SIZE_ESTACK);
- make_oper(&euop, 0, estack_underflow);
- ref_stack_init(pes, &stk, ES_GUARD_UNDER, ES_GUARD_OVER, &euop,
- smem, NULL);
- ref_stack_set_error_codes(pes, e_ExecStackUnderflow,
- e_execstackoverflow);
- /**************** E-STACK EXPANSION IS NYI. ****************/
- ref_stack_allow_expansion(pes, false);
- ref_stack_set_max_count(pes, MAX_ESTACK);
- stk.value.refs += REFS_SIZE_ESTACK;
+ ref_stack_t *pes = &pcst->exec_stack.stack;
+ ref euop;
+
+ r_set_size(&stk, REFS_SIZE_ESTACK);
+ make_oper(&euop, 0, estack_underflow);
+ ref_stack_init(pes, &stk, ES_GUARD_UNDER, ES_GUARD_OVER, &euop,
+ smem, NULL);
+ ref_stack_set_error_codes(pes, e_ExecStackUnderflow,
+ e_execstackoverflow);
+ /**************** E-STACK EXPANSION IS NYI. ****************/
+ ref_stack_allow_expansion(pes, false);
+ ref_stack_set_max_count(pes, MAX_ESTACK);
+ stk.value.refs += REFS_SIZE_ESTACK;
}
{
- ref_stack_t *pds = &pcst->dict_stack.stack;
+ ref_stack_t *pds = &pcst->dict_stack.stack;
- r_set_size(&stk, REFS_SIZE_DSTACK);
- ref_stack_init(pds, &stk, 0, 0, NULL, smem, NULL);
- ref_stack_set_error_codes(pds, e_dictstackunderflow,
- e_dictstackoverflow);
- ref_stack_set_max_count(pds, MAX_DSTACK);
+ r_set_size(&stk, REFS_SIZE_DSTACK);
+ ref_stack_init(pds, &stk, 0, 0, NULL, smem, NULL);
+ ref_stack_set_error_codes(pds, e_dictstackunderflow,
+ e_dictstackoverflow);
+ ref_stack_set_max_count(pds, MAX_DSTACK);
}
#undef REFS_SIZE_OSTACK
@@ -393,11 +393,11 @@ gs_interp_make_oper(ref * opref, op_proc_t proc, int idx)
int i;
for (i = num_special_ops; i > 0 && proc != interp1_op_defs[i].proc; --i)
- DO_NOTHING;
+ DO_NOTHING;
if (i > 0)
- make_tasv(opref, tx_op + (i - 1), a_executable, i, opproc, proc);
+ make_tasv(opref, tx_op + (i - 1), a_executable, i, opproc, proc);
else
- make_tasv(opref, t_operator, a_executable, idx, opproc, proc);
+ make_tasv(opref, t_operator, a_executable, idx, opproc, proc);
}
/*
@@ -411,9 +411,9 @@ interp_reclaim(i_ctx_t **pi_ctx_p, int space)
int code;
gs_register_struct_root(imemory_system, &ctx_root,
- (void **)pi_ctx_p, "interp_reclaim(pi_ctx_p)");
+ (void **)pi_ctx_p, "interp_reclaim(pi_ctx_p)");
code = (*idmemory->reclaim)(idmemory, space);
- i_ctx_p = *pi_ctx_p; /* may have moved */
+ i_ctx_p = *pi_ctx_p; /* may have moved */
gs_unregister_root(imemory_system, &ctx_root, "interp_reclaim(pi_ctx_p)");
return code;
}
@@ -431,16 +431,16 @@ interp_reclaim(i_ctx_t **pi_ctx_p, int space)
static int gs_call_interp(i_ctx_t **, ref *, int, int *, ref *);
int
gs_interpret(i_ctx_t **pi_ctx_p, ref * pref, int user_errors, int *pexit_code,
- ref * perror_object)
+ ref * perror_object)
{
i_ctx_t *i_ctx_p = *pi_ctx_p;
gs_gc_root_t error_root;
int code;
gs_register_ref_root(imemory_system, &error_root,
- (void **)&perror_object, "gs_interpret");
+ (void **)&perror_object, "gs_interpret");
code = gs_call_interp(pi_ctx_p, pref, user_errors, pexit_code,
- perror_object);
+ perror_object);
i_ctx_p = *pi_ctx_p;
gs_unregister_root(imemory_system, &error_root, "gs_interpret");
/* Avoid a dangling reference to a stack-allocated GC signal. */
@@ -449,7 +449,7 @@ gs_interpret(i_ctx_t **pi_ctx_p, ref * pref, int user_errors, int *pexit_code,
}
static int
gs_call_interp(i_ctx_t **pi_ctx_p, ref * pref, int user_errors,
- int *pexit_code, ref * perror_object)
+ int *pexit_code, ref * perror_object)
{
ref *epref = pref;
ref doref;
@@ -466,181 +466,181 @@ again:
/* Avoid a dangling error object that might get traced by a future GC. */
make_null(perror_object);
o_stack.requested = e_stack.requested = d_stack.requested = 0;
- while (gc_signal) { /* Some routine below triggered a GC. */
- gs_gc_root_t epref_root;
-
- gc_signal = 0;
- /* Make sure that doref will get relocated properly if */
- /* a garbage collection happens with epref == &doref. */
- gs_register_ref_root(imemory_system, &epref_root,
- (void **)&epref, "gs_call_interp(epref)");
- code = interp_reclaim(pi_ctx_p, -1);
- i_ctx_p = *pi_ctx_p;
- gs_unregister_root(imemory_system, &epref_root,
- "gs_call_interp(epref)");
- if (code < 0)
- return code;
+ while (gc_signal) { /* Some routine below triggered a GC. */
+ gs_gc_root_t epref_root;
+
+ gc_signal = 0;
+ /* Make sure that doref will get relocated properly if */
+ /* a garbage collection happens with epref == &doref. */
+ gs_register_ref_root(imemory_system, &epref_root,
+ (void **)&epref, "gs_call_interp(epref)");
+ code = interp_reclaim(pi_ctx_p, -1);
+ i_ctx_p = *pi_ctx_p;
+ gs_unregister_root(imemory_system, &epref_root,
+ "gs_call_interp(epref)");
+ if (code < 0)
+ return code;
}
code = interp(pi_ctx_p, epref, perror_object);
i_ctx_p = *pi_ctx_p;
if (!r_has_type(&i_ctx_p->error_object, t__invalid)) {
- *perror_object = i_ctx_p->error_object;
- make_t(&i_ctx_p->error_object, t__invalid);
+ *perror_object = i_ctx_p->error_object;
+ make_t(&i_ctx_p->error_object, t__invalid);
}
/* Prevent a dangling reference to the GC signal in ticks_left */
/* in the frame of interp, but be prepared to do a GC if */
/* an allocation in this routine asks for it. */
set_gc_signal(i_ctx_p, &gc_signal, 1);
- if (esp < esbot) /* popped guard entry */
- esp = esbot;
+ if (esp < esbot) /* popped guard entry */
+ esp = esbot;
switch (code) {
- case e_Fatal:
- *pexit_code = 255;
- return code;
- case e_Quit:
- *perror_object = osp[-1];
- *pexit_code = code = osp->value.intval;
- osp -= 2;
- return
- (code == 0 ? e_Quit :
- code < 0 && code > -100 ? code : e_Fatal);
- case e_InterpreterExit:
- return 0;
- case e_ExecStackUnderflow:
+ case e_Fatal:
+ *pexit_code = 255;
+ return code;
+ case e_Quit:
+ *perror_object = osp[-1];
+ *pexit_code = code = osp->value.intval;
+ osp -= 2;
+ return
+ (code == 0 ? e_Quit :
+ code < 0 && code > -100 ? code : e_Fatal);
+ case e_InterpreterExit:
+ return 0;
+ case e_ExecStackUnderflow:
/****** WRONG -- must keep mark blocks intact ******/
- ref_stack_pop_block(&e_stack);
- doref = *perror_object;
- epref = &doref;
- goto again;
- case e_VMreclaim:
- /* Do the GC and continue. */
- code = interp_reclaim(pi_ctx_p,
- (osp->value.intval == 2 ?
- avm_global : avm_local));
- i_ctx_p = *pi_ctx_p;
- /****** What if code < 0? ******/
- make_oper(&doref, 0, zpop);
- epref = &doref;
- goto again;
- case e_NeedInput:
- case e_interrupt:
- return code;
+ ref_stack_pop_block(&e_stack);
+ doref = *perror_object;
+ epref = &doref;
+ goto again;
+ case e_VMreclaim:
+ /* Do the GC and continue. */
+ code = interp_reclaim(pi_ctx_p,
+ (osp->value.intval == 2 ?
+ avm_global : avm_local));
+ i_ctx_p = *pi_ctx_p;
+ /****** What if code < 0? ******/
+ make_oper(&doref, 0, zpop);
+ epref = &doref;
+ goto again;
+ case e_NeedInput:
+ case e_interrupt:
+ return code;
}
/* Adjust osp in case of operand stack underflow */
if (osp < osbot - 1)
- osp = osbot - 1;
+ osp = osbot - 1;
/* We have to handle stack over/underflow specially, because */
/* we might be able to recover by adding or removing a block. */
switch (code) {
- case e_dictstackoverflow:
- /* We don't have to handle this specially: */
- /* The only places that could generate it */
- /* use check_dstack, which does a ref_stack_extend, */
- /* so if` we get this error, it's a real one. */
- if (osp >= ostop) {
- if ((ccode = ref_stack_extend(&o_stack, 1)) < 0)
- return ccode;
- }
+ case e_dictstackoverflow:
+ /* We don't have to handle this specially: */
+ /* The only places that could generate it */
+ /* use check_dstack, which does a ref_stack_extend, */
+ /* so if` we get this error, it's a real one. */
+ if (osp >= ostop) {
+ if ((ccode = ref_stack_extend(&o_stack, 1)) < 0)
+ return ccode;
+ }
/* Skip system dictionaries for CET 20-02-02 */
- ccode = copy_stack(i_ctx_p, &d_stack, min_dstack_size, &saref);
- if (ccode < 0)
- return ccode;
- ref_stack_pop_to(&d_stack, min_dstack_size);
- dict_set_top();
- *++osp = saref;
- break;
- case e_dictstackunderflow:
- if (ref_stack_pop_block(&d_stack) >= 0) {
- dict_set_top();
- doref = *perror_object;
- epref = &doref;
- goto again;
- }
- break;
- case e_execstackoverflow:
- /* We don't have to handle this specially: */
- /* The only places that could generate it */
- /* use check_estack, which does a ref_stack_extend, */
- /* so if we get this error, it's a real one. */
- if (osp >= ostop) {
- if ((ccode = ref_stack_extend(&o_stack, 1)) < 0)
- return ccode;
- }
- ccode = copy_stack(i_ctx_p, &e_stack, 0, &saref);
- if (ccode < 0)
- return ccode;
- {
- uint count = ref_stack_count(&e_stack);
- uint limit = ref_stack_max_count(&e_stack) - ES_HEADROOM;
-
- if (count > limit) {
- /*
- * If there is an e-stack mark within MIN_BLOCK_ESTACK of
- * the new top, cut the stack back to remove the mark.
- */
- int skip = count - limit;
- int i;
-
- for (i = skip; i < skip + MIN_BLOCK_ESTACK; ++i) {
- const ref *ep = ref_stack_index(&e_stack, i);
-
- if (r_has_type_attrs(ep, t_null, a_executable)) {
- skip = i + 1;
- break;
- }
- }
- pop_estack(i_ctx_p, skip);
- }
- }
- *++osp = saref;
- break;
- case e_stackoverflow:
- if (ref_stack_extend(&o_stack, o_stack.requested) >= 0) { /* We can't just re-execute the object, because */
- /* it might be a procedure being pushed as a */
- /* literal. We check for this case specially. */
- doref = *perror_object;
- if (r_is_proc(&doref)) {
- *++osp = doref;
- make_null_proc(&doref);
- }
- epref = &doref;
- goto again;
- }
- ccode = copy_stack(i_ctx_p, &o_stack, 0, &saref);
- if (ccode < 0)
- return ccode;
- ref_stack_clear(&o_stack);
- *++osp = saref;
- break;
- case e_stackunderflow:
- if (ref_stack_pop_block(&o_stack) >= 0) {
- doref = *perror_object;
- epref = &doref;
- goto again;
- }
- break;
+ ccode = copy_stack(i_ctx_p, &d_stack, min_dstack_size, &saref);
+ if (ccode < 0)
+ return ccode;
+ ref_stack_pop_to(&d_stack, min_dstack_size);
+ dict_set_top();
+ *++osp = saref;
+ break;
+ case e_dictstackunderflow:
+ if (ref_stack_pop_block(&d_stack) >= 0) {
+ dict_set_top();
+ doref = *perror_object;
+ epref = &doref;
+ goto again;
+ }
+ break;
+ case e_execstackoverflow:
+ /* We don't have to handle this specially: */
+ /* The only places that could generate it */
+ /* use check_estack, which does a ref_stack_extend, */
+ /* so if we get this error, it's a real one. */
+ if (osp >= ostop) {
+ if ((ccode = ref_stack_extend(&o_stack, 1)) < 0)
+ return ccode;
+ }
+ ccode = copy_stack(i_ctx_p, &e_stack, 0, &saref);
+ if (ccode < 0)
+ return ccode;
+ {
+ uint count = ref_stack_count(&e_stack);
+ uint limit = ref_stack_max_count(&e_stack) - ES_HEADROOM;
+
+ if (count > limit) {
+ /*
+ * If there is an e-stack mark within MIN_BLOCK_ESTACK of
+ * the new top, cut the stack back to remove the mark.
+ */
+ int skip = count - limit;
+ int i;
+
+ for (i = skip; i < skip + MIN_BLOCK_ESTACK; ++i) {
+ const ref *ep = ref_stack_index(&e_stack, i);
+
+ if (r_has_type_attrs(ep, t_null, a_executable)) {
+ skip = i + 1;
+ break;
+ }
+ }
+ pop_estack(i_ctx_p, skip);
+ }
+ }
+ *++osp = saref;
+ break;
+ case e_stackoverflow:
+ if (ref_stack_extend(&o_stack, o_stack.requested) >= 0) { /* We can't just re-execute the object, because */
+ /* it might be a procedure being pushed as a */
+ /* literal. We check for this case specially. */
+ doref = *perror_object;
+ if (r_is_proc(&doref)) {
+ *++osp = doref;
+ make_null_proc(&doref);
+ }
+ epref = &doref;
+ goto again;
+ }
+ ccode = copy_stack(i_ctx_p, &o_stack, 0, &saref);
+ if (ccode < 0)
+ return ccode;
+ ref_stack_clear(&o_stack);
+ *++osp = saref;
+ break;
+ case e_stackunderflow:
+ if (ref_stack_pop_block(&o_stack) >= 0) {
+ doref = *perror_object;
+ epref = &doref;
+ goto again;
+ }
+ break;
}
if (user_errors < 0)
- return code;
+ return code;
if (gs_errorname(i_ctx_p, code, &error_name) < 0)
- return code; /* out-of-range error code! */
+ return code; /* out-of-range error code! */
/*
* For greater Adobe compatibility, only the standard PostScript errors
* are defined in errordict; the rest are in gserrordict.
*/
if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 ||
- (dict_find(perrordict, &error_name, &epref) <= 0 &&
- (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
- dict_find(perrordict, &error_name, &epref) <= 0))
- )
- return code; /* error name not in errordict??? */
+ (dict_find(perrordict, &error_name, &epref) <= 0 &&
+ (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
+ dict_find(perrordict, &error_name, &epref) <= 0))
+ )
+ return code; /* error name not in errordict??? */
doref = *epref;
epref = &doref;
/* Push the error object on the operand stack if appropriate. */
if (!ERROR_IS_INTERRUPT(code)) {
- /* Replace the error object if within an oparray or .errorexec. */
- *++osp = *perror_object;
- errorexec_find(i_ctx_p, osp);
+ /* Replace the error object if within an oparray or .errorexec. */
+ *++osp = *perror_object;
+ errorexec_find(i_ctx_p, osp);
}
goto again;
}
@@ -658,21 +658,21 @@ set_gc_signal(i_ctx_t *i_ctx_p, int *psignal, int value)
int i;
for (i = 0; i < countof(idmemory->spaces_indexed); i++) {
- gs_ref_memory_t *mem = idmemory->spaces_indexed[i];
- gs_ref_memory_t *mem_stable;
-
- if (mem == 0)
- continue;
- for (;; mem = mem_stable) {
- mem_stable = (gs_ref_memory_t *)
- gs_memory_stable((gs_memory_t *)mem);
- gs_memory_gc_status(mem, &stat);
- stat.psignal = psignal;
- stat.signal_value = value;
- gs_memory_set_gc_status(mem, &stat);
- if (mem_stable == mem)
- break;
- }
+ gs_ref_memory_t *mem = idmemory->spaces_indexed[i];
+ gs_ref_memory_t *mem_stable;
+
+ if (mem == 0)
+ continue;
+ for (;; mem = mem_stable) {
+ mem_stable = (gs_ref_memory_t *)
+ gs_memory_stable((gs_memory_t *)mem);
+ gs_memory_gc_status(mem, &stat);
+ stat.psignal = psignal;
+ stat.signal_value = value;
+ gs_memory_set_gc_status(mem, &stat);
+ if (mem_stable == mem)
+ break;
+ }
}
}
@@ -691,8 +691,8 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr)
ialloc_set_space(idmemory, avm_local);
code = ialloc_ref_array(arr, a_all, size, "copy_stack");
if (code >= 0)
- code = ref_stack_store(pstack, arr, size, 0, 1, true, idmemory,
- "copy_stack");
+ code = ref_stack_store(pstack, arr, size, 0, 1, true, idmemory,
+ "copy_stack");
ialloc_set_space(idmemory, save_space);
return code;
}
@@ -704,9 +704,9 @@ gs_errorname(i_ctx_t *i_ctx_p, int code, ref * perror_name)
ref *perrordict, *pErrorNames;
if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 ||
- dict_find_string(systemdict, "ErrorNames", &pErrorNames) <= 0
- )
- return_error(e_undefined); /* errordict or ErrorNames not found?! */
+ dict_find_string(systemdict, "ErrorNames", &pErrorNames) <= 0
+ )
+ return_error(e_undefined); /* errordict or ErrorNames not found?! */
return array_get(imemory, pErrorNames, (long)(-code - 1), perror_name);
}
@@ -720,12 +720,12 @@ gs_errorinfo_put_string(i_ctx_t *i_ctx_p, const char *str)
int code = string_to_ref(str, &rstr, iimemory, "gs_errorinfo_put_string");
if (code < 0)
- return code;
+ return code;
if (dict_find_string(systemdict, "$error", &pderror) <= 0 ||
- !r_has_type(pderror, t_dictionary) ||
- idict_put_string(pderror, "errorinfo", &rstr) < 0
- )
- return_error(e_Fatal);
+ !r_has_type(pderror, t_dictionary) ||
+ idict_put_string(pderror, "errorinfo", &rstr) < 0
+ )
+ return_error(e_Fatal);
return 0;
}
@@ -764,14 +764,14 @@ interp(i_ctx_t **pi_ctx_p /* context for execution, updated if resched */,
# define IREF ((const ref *)iref_packed)
#endif
#define SET_IREF(rp) (iref_packed = (const ref_packed *)(rp))
- register int icount = 0; /* # of consecutive tokens at iref */
- register os_ptr iosp = osp; /* private copy of osp */
- register es_ptr iesp = esp; /* private copy of esp */
+ register int icount = 0; /* # of consecutive tokens at iref */
+ register os_ptr iosp = osp; /* private copy of osp */
+ register es_ptr iesp = esp; /* private copy of esp */
int code;
- ref token; /* token read from file or string, */
- /* must be declared in this scope */
+ ref token; /* token read from file or string, */
+ /* must be declared in this scope */
register const ref *pvalue = 0;
- uint opindex; /* needed for oparrays */
+ uint opindex; /* needed for oparrays */
os_ptr whichp;
/*
@@ -783,10 +783,10 @@ interp(i_ctx_t **pi_ctx_p /* context for execution, updated if resched */,
* will remain available on Intel processors.
*/
struct interp_error_s {
- int code;
- int line;
- const ref *obj;
- ref full;
+ int code;
+ int line;
+ const ref *obj;
+ ref full;
} ierror;
/*
@@ -866,51 +866,51 @@ interp(i_ctx_t **pi_ctx_p /* context for execution, updated if resched */,
/* so we push the argument on the estack and enter */
/* the loop at the bottom. */
if (iesp >= estop)
- return_with_error(e_execstackoverflow, pref);
+ return_with_error(e_execstackoverflow, pref);
++iesp;
ref_assign_inline(iesp, pref);
goto bot;
top:
- /*
- * This is the top of the interpreter loop.
- * iref points to the ref being interpreted.
- * Note that this might be an element of a packed array,
- * not a real ref: we carefully arranged the first 16 bits of
- * a ref and of a packed array element so they could be distinguished
- * from each other. (See ghost.h and packed.h for more detail.)
- */
+ /*
+ * This is the top of the interpreter loop.
+ * iref points to the ref being interpreted.
+ * Note that this might be an element of a packed array,
+ * not a real ref: we carefully arranged the first 16 bits of
+ * a ref and of a packed array element so they could be distinguished
+ * from each other. (See ghost.h and packed.h for more detail.)
+ */
INCR(top);
#ifdef DEBUG
/* Do a little validation on the top o-stack entry. */
if (iosp >= osbot &&
- (r_type(iosp) == t__invalid || r_type(iosp) >= tx_next_op)
- ) {
- lprintf("Invalid value on o-stack!\n");
- return_with_error_iref(e_Fatal);
+ (r_type(iosp) == t__invalid || r_type(iosp) >= tx_next_op)
+ ) {
+ lprintf("Invalid value on o-stack!\n");
+ return_with_error_iref(e_Fatal);
}
if (gs_debug['I'] ||
- (gs_debug['i'] &&
- (r_is_packed(iref_packed) ?
- r_packed_is_name(iref_packed) :
- r_has_type(IREF, t_name)))
- ) {
- os_ptr save_osp = osp; /* avoid side-effects */
- es_ptr save_esp = esp;
-
- osp = iosp;
- esp = iesp;
- dlprintf5("d%u,e%u<%u>0x%lx(%d): ",
- ref_stack_count(&d_stack), ref_stack_count(&e_stack),
- ref_stack_count(&o_stack), (ulong)IREF, icount);
- debug_print_ref(imemory, IREF);
- if (iosp >= osbot) {
- dputs(" // ");
- debug_print_ref(imemory, iosp);
- }
- dputc('\n');
- osp = save_osp;
- esp = save_esp;
- dflush();
+ (gs_debug['i'] &&
+ (r_is_packed(iref_packed) ?
+ r_packed_is_name(iref_packed) :
+ r_has_type(IREF, t_name)))
+ ) {
+ os_ptr save_osp = osp; /* avoid side-effects */
+ es_ptr save_esp = esp;
+
+ osp = iosp;
+ esp = iesp;
+ dlprintf5("d%u,e%u<%u>0x%lx(%d): ",
+ ref_stack_count(&d_stack), ref_stack_count(&e_stack),
+ ref_stack_count(&o_stack), (ulong)IREF, icount);
+ debug_print_ref(imemory, IREF);
+ if (iosp >= osbot) {
+ dputs(" // ");
+ debug_print_ref(imemory, iosp);
+ }
+ dputc('\n');
+ osp = save_osp;
+ esp = save_esp;
+ dflush();
}
#endif
/* Objects that have attributes (arrays, dictionaries, files, and strings) */
@@ -927,23 +927,23 @@ interp(i_ctx_t **pi_ctx_p /* context for execution, updated if resched */,
* What a nuisance!
*/
switch (r_type_xe(iref_packed)) {
- /* Access errors. */
+ /* Access errors. */
#define cases_invalid()\
case plain(t__invalid): case plain_exec(t__invalid)
- cases_invalid():
- return_with_error_iref(e_Fatal);
+ cases_invalid():
+ return_with_error_iref(e_Fatal);
#define cases_nox()\
case nox_exec(t_array): case nox_exec(t_dictionary):\
case nox_exec(t_file): case nox_exec(t_string):\
case nox_exec(t_mixedarray): case nox_exec(t_shortarray)
- cases_nox():
- return_with_error_iref(e_invalidaccess);
- /*
- * Literal objects. We have to enumerate all the types.
- * In fact, we have to include some extra plain_exec entries
- * just to populate the switch. We break them up into groups
- * to avoid overflowing some preprocessors.
- */
+ cases_nox():
+ return_with_error_iref(e_invalidaccess);
+ /*
+ * Literal objects. We have to enumerate all the types.
+ * In fact, we have to include some extra plain_exec entries
+ * just to populate the switch. We break them up into groups
+ * to avoid overflowing some preprocessors.
+ */
#define cases_lit_1()\
case lit(t_array): case nox(t_array):\
case plain(t_boolean): case plain_exec(t_boolean):\
@@ -968,673 +968,673 @@ interp(i_ctx_t **pi_ctx_p /* context for execution, updated if resched */,
case plain(t_device): case plain_exec(t_device):\
case plain(t_struct): case plain_exec(t_struct):\
case plain(t_astruct): case plain_exec(t_astruct)
- /* Executable arrays are treated as literals in direct execution. */
+ /* Executable arrays are treated as literals in direct execution. */
#define cases_lit_array()\
case exec(t_array): case exec(t_mixedarray): case exec(t_shortarray)
- cases_lit_1():
- cases_lit_2():
- cases_lit_3():
- cases_lit_4():
- cases_lit_5():
- INCR(lit);
- break;
- cases_lit_array():
- INCR(lit_array);
- break;
- /* Special operators. */
- case plain_exec(tx_op_add):
-x_add: INCR(x_add);
- if ((code = zop_add(iosp)) < 0)
- return_with_error_tx_op(code);
- iosp--;
- next_either();
- case plain_exec(tx_op_def):
-x_def: INCR(x_def);
- osp = iosp; /* sync o_stack */
- if ((code = zop_def(i_ctx_p)) < 0)
- return_with_error_tx_op(code);
- iosp -= 2;
- next_either();
- case plain_exec(tx_op_dup):
-x_dup: INCR(x_dup);
- if (iosp < osbot)
- return_with_error_tx_op(e_stackunderflow);
- if (iosp >= ostop) {
- o_stack.requested = 1;
+ cases_lit_1():
+ cases_lit_2():
+ cases_lit_3():
+ cases_lit_4():
+ cases_lit_5():
+ INCR(lit);
+ break;
+ cases_lit_array():
+ INCR(lit_array);
+ break;
+ /* Special operators. */
+ case plain_exec(tx_op_add):
+x_add: INCR(x_add);
+ if ((code = zop_add(iosp)) < 0)
+ return_with_error_tx_op(code);
+ iosp--;
+ next_either();
+ case plain_exec(tx_op_def):
+x_def: INCR(x_def);
+ osp = iosp; /* sync o_stack */
+ if ((code = zop_def(i_ctx_p)) < 0)
+ return_with_error_tx_op(code);
+ iosp -= 2;
+ next_either();
+ case plain_exec(tx_op_dup):
+x_dup: INCR(x_dup);
+ if (iosp < osbot)
+ return_with_error_tx_op(e_stackunderflow);
+ if (iosp >= ostop) {
+ o_stack.requested = 1;
return_with_error_tx_op(e_stackoverflow);
}
- iosp++;
- ref_assign_inline(iosp, iosp - 1);
- next_either();
- case plain_exec(tx_op_exch):
-x_exch: INCR(x_exch);
- if (iosp <= osbot)
- return_with_error_tx_op(e_stackunderflow);
- ref_assign_inline(&token, iosp);
- ref_assign_inline(iosp, iosp - 1);
- ref_assign_inline(iosp - 1, &token);
- next_either();
- case plain_exec(tx_op_if):
-x_if: INCR(x_if);
- if (!r_is_proc(iosp))
- return_with_error_tx_op(check_proc_failed(iosp));
- if (!r_has_type(iosp - 1, t_boolean))
- return_with_error_tx_op((iosp <= osbot ?
- e_stackunderflow : e_typecheck));
- if (!iosp[-1].value.boolval) {
- iosp -= 2;
- next_either();
- }
- if (iesp >= estop)
- return_with_error_tx_op(e_execstackoverflow);
- store_state_either(iesp);
- whichp = iosp;
- iosp -= 2;
- goto ifup;
- case plain_exec(tx_op_ifelse):
+ iosp++;
+ ref_assign_inline(iosp, iosp - 1);
+ next_either();
+ case plain_exec(tx_op_exch):
+x_exch: INCR(x_exch);
+ if (iosp <= osbot)
+ return_with_error_tx_op(e_stackunderflow);
+ ref_assign_inline(&token, iosp);
+ ref_assign_inline(iosp, iosp - 1);
+ ref_assign_inline(iosp - 1, &token);
+ next_either();
+ case plain_exec(tx_op_if):
+x_if: INCR(x_if);
+ if (!r_is_proc(iosp))
+ return_with_error_tx_op(check_proc_failed(iosp));
+ if (!r_has_type(iosp - 1, t_boolean))
+ return_with_error_tx_op((iosp <= osbot ?
+ e_stackunderflow : e_typecheck));
+ if (!iosp[-1].value.boolval) {
+ iosp -= 2;
+ next_either();
+ }
+ if (iesp >= estop)
+ return_with_error_tx_op(e_execstackoverflow);
+ store_state_either(iesp);
+ whichp = iosp;
+ iosp -= 2;
+ goto ifup;
+ case plain_exec(tx_op_ifelse):
x_ifelse: INCR(x_ifelse);
- if (!r_is_proc(iosp))
- return_with_error_tx_op(check_proc_failed(iosp));
- if (!r_is_proc(iosp - 1))
- return_with_error_tx_op(check_proc_failed(iosp - 1));
- if (!r_has_type(iosp - 2, t_boolean))
- return_with_error_tx_op((iosp < osbot + 2 ?
- e_stackunderflow : e_typecheck));
- if (iesp >= estop)
- return_with_error_tx_op(e_execstackoverflow);
- store_state_either(iesp);
- whichp = (iosp[-2].value.boolval ? iosp - 1 : iosp);
- iosp -= 3;
- /* Open code "up" for the array case(s) */
- ifup:if ((icount = r_size(whichp) - 1) <= 0) {
- if (icount < 0)
- goto up; /* 0-element proc */
- SET_IREF(whichp->value.refs); /* 1-element proc */
- if (--ticks_left > 0)
- goto top;
- }
- ++iesp;
- /* Do a ref_assign, but also set iref. */
- iesp->tas = whichp->tas;
- SET_IREF(iesp->value.refs = whichp->value.refs);
- if (--ticks_left > 0)
- goto top;
- goto slice;
- case plain_exec(tx_op_index):
+ if (!r_is_proc(iosp))
+ return_with_error_tx_op(check_proc_failed(iosp));
+ if (!r_is_proc(iosp - 1))
+ return_with_error_tx_op(check_proc_failed(iosp - 1));
+ if (!r_has_type(iosp - 2, t_boolean))
+ return_with_error_tx_op((iosp < osbot + 2 ?
+ e_stackunderflow : e_typecheck));
+ if (iesp >= estop)
+ return_with_error_tx_op(e_execstackoverflow);
+ store_state_either(iesp);
+ whichp = (iosp[-2].value.boolval ? iosp - 1 : iosp);
+ iosp -= 3;
+ /* Open code "up" for the array case(s) */
+ ifup:if ((icount = r_size(whichp) - 1) <= 0) {
+ if (icount < 0)
+ goto up; /* 0-element proc */
+ SET_IREF(whichp->value.refs); /* 1-element proc */
+ if (--ticks_left > 0)
+ goto top;
+ }
+ ++iesp;
+ /* Do a ref_assign, but also set iref. */
+ iesp->tas = whichp->tas;
+ SET_IREF(iesp->value.refs = whichp->value.refs);
+ if (--ticks_left > 0)
+ goto top;
+ goto slice;
+ case plain_exec(tx_op_index):
x_index: INCR(x_index);
- osp = iosp; /* zindex references o_stack */
- if ((code = zindex(i_ctx_p)) < 0)
- return_with_error_tx_op(code);
- next_either();
- case plain_exec(tx_op_pop):
-x_pop: INCR(x_pop);
- if (iosp < osbot)
- return_with_error_tx_op(e_stackunderflow);
- iosp--;
- next_either();
- case plain_exec(tx_op_roll):
-x_roll: INCR(x_roll);
- osp = iosp; /* zroll references o_stack */
- if ((code = zroll(i_ctx_p)) < 0)
- return_with_error_tx_op(code);
- iosp -= 2;
- next_either();
- case plain_exec(tx_op_sub):
-x_sub: INCR(x_sub);
- if ((code = zop_sub(iosp)) < 0)
- return_with_error_tx_op(code);
- iosp--;
- next_either();
- /* Executable types. */
- case plain_exec(t_null):
- goto bot;
- case plain_exec(t_oparray):
- /* Replace with the definition and go again. */
- INCR(exec_array);
- opindex = op_index(IREF);
- pvalue = IREF->value.const_refs;
- opst: /* Prepare to call a t_oparray procedure in *pvalue. */
- store_state(iesp);
- oppr: /* Record the stack depths in case of failure. */
- if (iesp >= estop - 4)
- return_with_error_iref(e_execstackoverflow);
- iesp += 5;
- osp = iosp; /* ref_stack_count_inline needs this */
- make_mark_estack(iesp - 4, es_other, oparray_cleanup);
- make_int(iesp - 3, opindex); /* for .errorexec effect */
- make_int(iesp - 2, ref_stack_count_inline(&o_stack));
- make_int(iesp - 1, ref_stack_count_inline(&d_stack));
- make_op_estack(iesp, oparray_pop);
- goto pr;
- prst: /* Prepare to call the procedure (array) in *pvalue. */
- store_state(iesp);
- pr: /* Call the array in *pvalue. State has been stored. */
- if ((icount = r_size(pvalue) - 1) <= 0) {
- if (icount < 0)
- goto up; /* 0-element proc */
- SET_IREF(pvalue->value.refs); /* 1-element proc */
- if (--ticks_left > 0)
- goto top;
- }
- if (iesp >= estop)
- return_with_error_iref(e_execstackoverflow);
- ++iesp;
- /* Do a ref_assign, but also set iref. */
- iesp->tas = pvalue->tas;
- SET_IREF(iesp->value.refs = pvalue->value.refs);
- if (--ticks_left > 0)
- goto top;
- goto slice;
- case plain_exec(t_operator):
- INCR(exec_operator);
- if (--ticks_left <= 0) { /* The following doesn't work, */
- /* and I can't figure out why. */
+ osp = iosp; /* zindex references o_stack */
+ if ((code = zindex(i_ctx_p)) < 0)
+ return_with_error_tx_op(code);
+ next_either();
+ case plain_exec(tx_op_pop):
+x_pop: INCR(x_pop);
+ if (iosp < osbot)
+ return_with_error_tx_op(e_stackunderflow);
+ iosp--;
+ next_either();
+ case plain_exec(tx_op_roll):
+x_roll: INCR(x_roll);
+ osp = iosp; /* zroll references o_stack */
+ if ((code = zroll(i_ctx_p)) < 0)
+ return_with_error_tx_op(code);
+ iosp -= 2;
+ next_either();
+ case plain_exec(tx_op_sub):
+x_sub: INCR(x_sub);
+ if ((code = zop_sub(iosp)) < 0)
+ return_with_error_tx_op(code);
+ iosp--;
+ next_either();
+ /* Executable types. */
+ case plain_exec(t_null):
+ goto bot;
+ case plain_exec(t_oparray):
+ /* Replace with the definition and go again. */
+ INCR(exec_array);
+ opindex = op_index(IREF);
+ pvalue = IREF->value.const_refs;
+ opst: /* Prepare to call a t_oparray procedure in *pvalue. */
+ store_state(iesp);
+ oppr: /* Record the stack depths in case of failure. */
+ if (iesp >= estop - 4)
+ return_with_error_iref(e_execstackoverflow);
+ iesp += 5;
+ osp = iosp; /* ref_stack_count_inline needs this */
+ make_mark_estack(iesp - 4, es_other, oparray_cleanup);
+ make_int(iesp - 3, opindex); /* for .errorexec effect */
+ make_int(iesp - 2, ref_stack_count_inline(&o_stack));
+ make_int(iesp - 1, ref_stack_count_inline(&d_stack));
+ make_op_estack(iesp, oparray_pop);
+ goto pr;
+ prst: /* Prepare to call the procedure (array) in *pvalue. */
+ store_state(iesp);
+ pr: /* Call the array in *pvalue. State has been stored. */
+ if ((icount = r_size(pvalue) - 1) <= 0) {
+ if (icount < 0)
+ goto up; /* 0-element proc */
+ SET_IREF(pvalue->value.refs); /* 1-element proc */
+ if (--ticks_left > 0)
+ goto top;
+ }
+ if (iesp >= estop)
+ return_with_error_iref(e_execstackoverflow);
+ ++iesp;
+ /* Do a ref_assign, but also set iref. */
+ iesp->tas = pvalue->tas;
+ SET_IREF(iesp->value.refs = pvalue->value.refs);
+ if (--ticks_left > 0)
+ goto top;
+ goto slice;
+ case plain_exec(t_operator):
+ INCR(exec_operator);
+ if (--ticks_left <= 0) { /* The following doesn't work, */
+ /* and I can't figure out why. */
/****** goto sst; ******/
- }
- esp = iesp; /* save for operator */
- osp = iosp; /* ditto */
- /* Operator routines take osp as an argument. */
- /* This is just a convenience, since they adjust */
- /* osp themselves to reflect the results. */
- /* Operators that (net) push information on the */
- /* operand stack must check for overflow: */
- /* this normally happens automatically through */
- /* the push macro (in oper.h). */
- /* Operators that do not typecheck their operands, */
- /* or take a variable number of arguments, */
- /* must check explicitly for stack underflow. */
- /* (See oper.h for more detail.) */
- /* Note that each case must set iosp = osp: */
- /* this is so we can switch on code without having to */
- /* store it and reload it (for dumb compilers). */
- switch (code = call_operator(real_opproc(IREF), i_ctx_p)) {
- case 0: /* normal case */
- case 1: /* alternative success case */
- iosp = osp;
- next();
- case o_push_estack: /* store the state and go to up */
- store_state(iesp);
- opush:iosp = osp;
- iesp = esp;
- if (--ticks_left > 0)
- goto up;
- goto slice;
- case o_pop_estack: /* just go to up */
- opop:iosp = osp;
- if (esp == iesp)
- goto bot;
- iesp = esp;
- goto up;
- case o_reschedule:
- store_state(iesp);
- goto res;
- case e_RemapColor:
-oe_remap: store_state(iesp);
-remap: if (iesp + 2 >= estop) {
- esp = iesp;
- code = ref_stack_extend(&e_stack, 2);
- if (code < 0)
- return_with_error_iref(code);
- iesp = esp;
- }
- packed_get(imemory, iref_packed, iesp + 1);
- make_oper(iesp + 2, 0,
- r_ptr(&istate->remap_color_info,
- int_remap_color_info_t)->proc);
- iesp += 2;
- goto up;
- }
- iosp = osp;
- iesp = esp;
- return_with_code_iref();
- case plain_exec(t_name):
- INCR(exec_name);
- pvalue = IREF->value.pname->pvalue;
- if (!pv_valid(pvalue)) {
- uint nidx = names_index(int_nt, IREF);
- uint htemp;
-
- INCR(find_name);
- if ((pvalue = dict_find_name_by_index_inline(nidx, htemp)) == 0)
- return_with_error_iref(e_undefined);
- }
- /* Dispatch on the type of the value. */
- /* Again, we have to over-populate the switch. */
- switch (r_type_xe(pvalue)) {
- cases_invalid():
- return_with_error_iref(e_Fatal);
- cases_nox(): /* access errors */
- return_with_error_iref(e_invalidaccess);
- cases_lit_1():
- cases_lit_2():
- cases_lit_3():
- cases_lit_4():
- cases_lit_5():
- INCR(name_lit);
- /* Just push the value */
- if (iosp >= ostop)
- return_with_stackoverflow(pvalue);
- ++iosp;
- ref_assign_inline(iosp, pvalue);
- next();
- case exec(t_array):
- case exec(t_mixedarray):
- case exec(t_shortarray):
- INCR(name_proc);
- /* This is an executable procedure, execute it. */
- goto prst;
- case plain_exec(tx_op_add):
- goto x_add;
- case plain_exec(tx_op_def):
- goto x_def;
- case plain_exec(tx_op_dup):
- goto x_dup;
- case plain_exec(tx_op_exch):
- goto x_exch;
- case plain_exec(tx_op_if):
- goto x_if;
- case plain_exec(tx_op_ifelse):
- goto x_ifelse;
- case plain_exec(tx_op_index):
- goto x_index;
- case plain_exec(tx_op_pop):
- goto x_pop;
- case plain_exec(tx_op_roll):
- goto x_roll;
- case plain_exec(tx_op_sub):
- goto x_sub;
- case plain_exec(t_null):
- goto bot;
- case plain_exec(t_oparray):
- INCR(name_oparray);
- opindex = op_index(pvalue);
- pvalue = (const ref *)pvalue->value.const_refs;
- goto opst;
- case plain_exec(t_operator):
- INCR(name_operator);
- { /* Shortcut for operators. */
- /* See above for the logic. */
- if (--ticks_left <= 0) { /* The following doesn't work, */
- /* and I can't figure out why. */
+ }
+ esp = iesp; /* save for operator */
+ osp = iosp; /* ditto */
+ /* Operator routines take osp as an argument. */
+ /* This is just a convenience, since they adjust */
+ /* osp themselves to reflect the results. */
+ /* Operators that (net) push information on the */
+ /* operand stack must check for overflow: */
+ /* this normally happens automatically through */
+ /* the push macro (in oper.h). */
+ /* Operators that do not typecheck their operands, */
+ /* or take a variable number of arguments, */
+ /* must check explicitly for stack underflow. */
+ /* (See oper.h for more detail.) */
+ /* Note that each case must set iosp = osp: */
+ /* this is so we can switch on code without having to */
+ /* store it and reload it (for dumb compilers). */
+ switch (code = call_operator(real_opproc(IREF), i_ctx_p)) {
+ case 0: /* normal case */
+ case 1: /* alternative success case */
+ iosp = osp;
+ next();
+ case o_push_estack: /* store the state and go to up */
+ store_state(iesp);
+ opush:iosp = osp;
+ iesp = esp;
+ if (--ticks_left > 0)
+ goto up;
+ goto slice;
+ case o_pop_estack: /* just go to up */
+ opop:iosp = osp;
+ if (esp == iesp)
+ goto bot;
+ iesp = esp;
+ goto up;
+ case o_reschedule:
+ store_state(iesp);
+ goto res;
+ case e_RemapColor:
+oe_remap: store_state(iesp);
+remap: if (iesp + 2 >= estop) {
+ esp = iesp;
+ code = ref_stack_extend(&e_stack, 2);
+ if (code < 0)
+ return_with_error_iref(code);
+ iesp = esp;
+ }
+ packed_get(imemory, iref_packed, iesp + 1);
+ make_oper(iesp + 2, 0,
+ r_ptr(&istate->remap_color_info,
+ int_remap_color_info_t)->proc);
+ iesp += 2;
+ goto up;
+ }
+ iosp = osp;
+ iesp = esp;
+ return_with_code_iref();
+ case plain_exec(t_name):
+ INCR(exec_name);
+ pvalue = IREF->value.pname->pvalue;
+ if (!pv_valid(pvalue)) {
+ uint nidx = names_index(int_nt, IREF);
+ uint htemp;
+
+ INCR(find_name);
+ if ((pvalue = dict_find_name_by_index_inline(nidx, htemp)) == 0)
+ return_with_error_iref(e_undefined);
+ }
+ /* Dispatch on the type of the value. */
+ /* Again, we have to over-populate the switch. */
+ switch (r_type_xe(pvalue)) {
+ cases_invalid():
+ return_with_error_iref(e_Fatal);
+ cases_nox(): /* access errors */
+ return_with_error_iref(e_invalidaccess);
+ cases_lit_1():
+ cases_lit_2():
+ cases_lit_3():
+ cases_lit_4():
+ cases_lit_5():
+ INCR(name_lit);
+ /* Just push the value */
+ if (iosp >= ostop)
+ return_with_stackoverflow(pvalue);
+ ++iosp;
+ ref_assign_inline(iosp, pvalue);
+ next();
+ case exec(t_array):
+ case exec(t_mixedarray):
+ case exec(t_shortarray):
+ INCR(name_proc);
+ /* This is an executable procedure, execute it. */
+ goto prst;
+ case plain_exec(tx_op_add):
+ goto x_add;
+ case plain_exec(tx_op_def):
+ goto x_def;
+ case plain_exec(tx_op_dup):
+ goto x_dup;
+ case plain_exec(tx_op_exch):
+ goto x_exch;
+ case plain_exec(tx_op_if):
+ goto x_if;
+ case plain_exec(tx_op_ifelse):
+ goto x_ifelse;
+ case plain_exec(tx_op_index):
+ goto x_index;
+ case plain_exec(tx_op_pop):
+ goto x_pop;
+ case plain_exec(tx_op_roll):
+ goto x_roll;
+ case plain_exec(tx_op_sub):
+ goto x_sub;
+ case plain_exec(t_null):
+ goto bot;
+ case plain_exec(t_oparray):
+ INCR(name_oparray);
+ opindex = op_index(pvalue);
+ pvalue = (const ref *)pvalue->value.const_refs;
+ goto opst;
+ case plain_exec(t_operator):
+ INCR(name_operator);
+ { /* Shortcut for operators. */
+ /* See above for the logic. */
+ if (--ticks_left <= 0) { /* The following doesn't work, */
+ /* and I can't figure out why. */
/****** goto sst; ******/
- }
- esp = iesp;
- osp = iosp;
- switch (code = call_operator(real_opproc(pvalue),
- i_ctx_p)
- ) {
- case 0: /* normal case */
- case 1: /* alternative success case */
- iosp = osp;
- next();
- case o_push_estack:
- store_state(iesp);
- goto opush;
- case o_pop_estack:
- goto opop;
- case o_reschedule:
- store_state(iesp);
- goto res;
- case e_RemapColor:
- goto oe_remap;
- }
- iosp = osp;
- iesp = esp;
- return_with_error(code, pvalue);
- }
- case plain_exec(t_name):
- case exec(t_file):
- case exec(t_string):
- default:
- /* Not a procedure, reinterpret it. */
- store_state(iesp);
- icount = 0;
- SET_IREF(pvalue);
- goto top;
- }
- case exec(t_file):
- { /* Executable file. Read the next token and interpret it. */
- stream *s;
- scanner_state sstate;
-
- check_read_known_file(i_ctx_p, s, IREF, return_with_error_iref);
- rt:
- if (iosp >= ostop) /* check early */
- return_with_stackoverflow_iref();
- osp = iosp; /* scan_token uses ostack */
- scanner_init_options(&sstate, IREF, i_ctx_p->scanner_options);
- again:
- code = scan_token(i_ctx_p, &token, &sstate);
- iosp = osp; /* ditto */
- switch (code) {
- case 0: /* read a token */
- /* It's worth checking for literals, which make up */
- /* the majority of input tokens, before storing the */
- /* state on the e-stack. Note that because of //, */
- /* the token may have *any* type and attributes. */
- /* Note also that executable arrays aren't executed */
- /* at the top level -- they're treated as literals. */
- if (!r_has_attr(&token, a_executable) ||
- r_is_array(&token)
- ) { /* If scan_token used the o-stack, */
- /* we know we can do a push now; if not, */
- /* the pre-check is still valid. */
- iosp++;
- ref_assign_inline(iosp, &token);
- goto rt;
- }
- store_state(iesp);
- /* Push the file on the e-stack */
- if (iesp >= estop)
- return_with_error_iref(e_execstackoverflow);
- esfile_set_cache(++iesp);
- ref_assign_inline(iesp, IREF);
- SET_IREF(&token);
- icount = 0;
- goto top;
- case e_undefined: /* //name undefined */
- scanner_error_object(i_ctx_p, &sstate, &token);
- return_with_error(code, &token);
- case scan_EOF: /* end of file */
- esfile_clear_cache();
- goto bot;
- case scan_BOS:
- /* Binary object sequences */
- /* ARE executed at the top level. */
- store_state(iesp);
- /* Push the file on the e-stack */
- if (iesp >= estop)
- return_with_error_iref(e_execstackoverflow);
- esfile_set_cache(++iesp);
- ref_assign_inline(iesp, IREF);
- pvalue = &token;
- goto pr;
- case scan_Refill:
- store_state(iesp);
- /* iref may point into the exec stack; */
- /* save its referent now. */
- ref_assign_inline(&token, IREF);
- /* Push the file on the e-stack */
- if (iesp >= estop)
- return_with_error_iref(e_execstackoverflow);
- ++iesp;
- ref_assign_inline(iesp, &token);
- esp = iesp;
- osp = iosp;
- code = scan_handle_refill(i_ctx_p, &sstate, true,
- ztokenexec_continue);
- scan_cont:
- iosp = osp;
- iesp = esp;
- switch (code) {
- case 0:
- iesp--; /* don't push the file */
- goto again; /* stacks are unchanged */
- case o_push_estack:
- esfile_clear_cache();
- if (--ticks_left > 0)
- goto up;
- goto slice;
- }
- /* must be an error */
- iesp--; /* don't push the file */
- return_with_code_iref();
- case scan_Comment:
- case scan_DSC_Comment: {
- /* See scan_Refill above for comments. */
- ref file_token;
-
- store_state(iesp);
- ref_assign_inline(&file_token, IREF);
- if (iesp >= estop)
- return_with_error_iref(e_execstackoverflow);
- ++iesp;
- ref_assign_inline(iesp, &file_token);
- esp = iesp;
- osp = iosp;
- code = ztoken_handle_comment(i_ctx_p,
- &sstate, &token,
- code, true, true,
- ztokenexec_continue);
- }
- goto scan_cont;
- default: /* error */
- ref_assign_inline(&token, IREF);
- scanner_error_object(i_ctx_p, &sstate, &token);
- return_with_error(code, &token);
- }
- }
- case exec(t_string):
- { /* Executable string. Read a token and interpret it. */
- stream ss;
- scanner_state sstate;
-
- s_init(&ss, NULL);
- sread_string(&ss, IREF->value.bytes, r_size(IREF));
- scanner_init_stream_options(&sstate, &ss, SCAN_FROM_STRING);
- osp = iosp; /* scan_token uses ostack */
- code = scan_token(i_ctx_p, &token, &sstate);
- iosp = osp; /* ditto */
- switch (code) {
- case 0: /* read a token */
- case scan_BOS: /* binary object sequence */
- store_state(iesp);
- /* If the updated string isn't empty, push it back */
- /* on the e-stack. */
- {
- uint size = sbufavailable(&ss);
-
- if (size) {
- if (iesp >= estop)
- return_with_error_iref(e_execstackoverflow);
- ++iesp;
- iesp->tas.type_attrs = IREF->tas.type_attrs;
- iesp->value.const_bytes = sbufptr(&ss);
- r_set_size(iesp, size);
- }
- }
- if (code == 0) {
- SET_IREF(&token);
- icount = 0;
- goto top;
- }
- /* Handle BOS specially */
- pvalue = &token;
- goto pr;
- case scan_EOF: /* end of string */
- goto bot;
- case scan_Refill: /* error */
- code = gs_note_error(e_syntaxerror);
- default: /* error */
- ref_assign_inline(&token, IREF);
- scanner_error_object(i_ctx_p, &sstate, &token);
- return_with_error(code, &token);
- }
- }
- /* Handle packed arrays here by re-dispatching. */
- /* This also picks up some anomalous cases of non-packed arrays. */
- default:
- {
- uint index;
-
- switch (*iref_packed >> r_packed_type_shift) {
- case pt_full_ref:
- case pt_full_ref + 1:
- INCR(p_full);
- if (iosp >= ostop)
- return_with_stackoverflow_iref();
- /* We know this can't be an executable object */
- /* requiring special handling, so we just push it. */
- ++iosp;
- /* We know that refs are properly aligned: */
- /* see packed.h for details. */
- ref_assign_inline(iosp, IREF);
- next();
- case pt_executable_operator:
- index = *iref_packed & packed_value_mask;
- if (--ticks_left <= 0) { /* The following doesn't work, */
- /* and I can't figure out why. */
+ }
+ esp = iesp;
+ osp = iosp;
+ switch (code = call_operator(real_opproc(pvalue),
+ i_ctx_p)
+ ) {
+ case 0: /* normal case */
+ case 1: /* alternative success case */
+ iosp = osp;
+ next();
+ case o_push_estack:
+ store_state(iesp);
+ goto opush;
+ case o_pop_estack:
+ goto opop;
+ case o_reschedule:
+ store_state(iesp);
+ goto res;
+ case e_RemapColor:
+ goto oe_remap;
+ }
+ iosp = osp;
+ iesp = esp;
+ return_with_error(code, pvalue);
+ }
+ case plain_exec(t_name):
+ case exec(t_file):
+ case exec(t_string):
+ default:
+ /* Not a procedure, reinterpret it. */
+ store_state(iesp);
+ icount = 0;
+ SET_IREF(pvalue);
+ goto top;
+ }
+ case exec(t_file):
+ { /* Executable file. Read the next token and interpret it. */
+ stream *s;
+ scanner_state sstate;
+
+ check_read_known_file(i_ctx_p, s, IREF, return_with_error_iref);
+ rt:
+ if (iosp >= ostop) /* check early */
+ return_with_stackoverflow_iref();
+ osp = iosp; /* gs_scan_token uses ostack */
+ gs_scanner_init_options(&sstate, IREF, i_ctx_p->scanner_options);
+ again:
+ code = gs_scan_token(i_ctx_p, &token, &sstate);
+ iosp = osp; /* ditto */
+ switch (code) {
+ case 0: /* read a token */
+ /* It's worth checking for literals, which make up */
+ /* the majority of input tokens, before storing the */
+ /* state on the e-stack. Note that because of //, */
+ /* the token may have *any* type and attributes. */
+ /* Note also that executable arrays aren't executed */
+ /* at the top level -- they're treated as literals. */
+ if (!r_has_attr(&token, a_executable) ||
+ r_is_array(&token)
+ ) { /* If gs_scan_token used the o-stack, */
+ /* we know we can do a push now; if not, */
+ /* the pre-check is still valid. */
+ iosp++;
+ ref_assign_inline(iosp, &token);
+ goto rt;
+ }
+ store_state(iesp);
+ /* Push the file on the e-stack */
+ if (iesp >= estop)
+ return_with_error_iref(e_execstackoverflow);
+ esfile_set_cache(++iesp);
+ ref_assign_inline(iesp, IREF);
+ SET_IREF(&token);
+ icount = 0;
+ goto top;
+ case e_undefined: /* //name undefined */
+ gs_scanner_error_object(i_ctx_p, &sstate, &token);
+ return_with_error(code, &token);
+ case scan_EOF: /* end of file */
+ esfile_clear_cache();
+ goto bot;
+ case scan_BOS:
+ /* Binary object sequences */
+ /* ARE executed at the top level. */
+ store_state(iesp);
+ /* Push the file on the e-stack */
+ if (iesp >= estop)
+ return_with_error_iref(e_execstackoverflow);
+ esfile_set_cache(++iesp);
+ ref_assign_inline(iesp, IREF);
+ pvalue = &token;
+ goto pr;
+ case scan_Refill:
+ store_state(iesp);
+ /* iref may point into the exec stack; */
+ /* save its referent now. */
+ ref_assign_inline(&token, IREF);
+ /* Push the file on the e-stack */
+ if (iesp >= estop)
+ return_with_error_iref(e_execstackoverflow);
+ ++iesp;
+ ref_assign_inline(iesp, &token);
+ esp = iesp;
+ osp = iosp;
+ code = gs_scan_handle_refill(i_ctx_p, &sstate, true,
+ ztokenexec_continue);
+ scan_cont:
+ iosp = osp;
+ iesp = esp;
+ switch (code) {
+ case 0:
+ iesp--; /* don't push the file */
+ goto again; /* stacks are unchanged */
+ case o_push_estack:
+ esfile_clear_cache();
+ if (--ticks_left > 0)
+ goto up;
+ goto slice;
+ }
+ /* must be an error */
+ iesp--; /* don't push the file */
+ return_with_code_iref();
+ case scan_Comment:
+ case scan_DSC_Comment: {
+ /* See scan_Refill above for comments. */
+ ref file_token;
+
+ store_state(iesp);
+ ref_assign_inline(&file_token, IREF);
+ if (iesp >= estop)
+ return_with_error_iref(e_execstackoverflow);
+ ++iesp;
+ ref_assign_inline(iesp, &file_token);
+ esp = iesp;
+ osp = iosp;
+ code = ztoken_handle_comment(i_ctx_p,
+ &sstate, &token,
+ code, true, true,
+ ztokenexec_continue);
+ }
+ goto scan_cont;
+ default: /* error */
+ ref_assign_inline(&token, IREF);
+ gs_scanner_error_object(i_ctx_p, &sstate, &token);
+ return_with_error(code, &token);
+ }
+ }
+ case exec(t_string):
+ { /* Executable string. Read a token and interpret it. */
+ stream ss;
+ scanner_state sstate;
+
+ s_init(&ss, NULL);
+ sread_string(&ss, IREF->value.bytes, r_size(IREF));
+ gs_scanner_init_stream_options(&sstate, &ss, SCAN_FROM_STRING);
+ osp = iosp; /* gs_scan_token uses ostack */
+ code = gs_scan_token(i_ctx_p, &token, &sstate);
+ iosp = osp; /* ditto */
+ switch (code) {
+ case 0: /* read a token */
+ case scan_BOS: /* binary object sequence */
+ store_state(iesp);
+ /* If the updated string isn't empty, push it back */
+ /* on the e-stack. */
+ {
+ uint size = sbufavailable(&ss);
+
+ if (size) {
+ if (iesp >= estop)
+ return_with_error_iref(e_execstackoverflow);
+ ++iesp;
+ iesp->tas.type_attrs = IREF->tas.type_attrs;
+ iesp->value.const_bytes = sbufptr(&ss);
+ r_set_size(iesp, size);
+ }
+ }
+ if (code == 0) {
+ SET_IREF(&token);
+ icount = 0;
+ goto top;
+ }
+ /* Handle BOS specially */
+ pvalue = &token;
+ goto pr;
+ case scan_EOF: /* end of string */
+ goto bot;
+ case scan_Refill: /* error */
+ code = gs_note_error(e_syntaxerror);
+ default: /* error */
+ ref_assign_inline(&token, IREF);
+ gs_scanner_error_object(i_ctx_p, &sstate, &token);
+ return_with_error(code, &token);
+ }
+ }
+ /* Handle packed arrays here by re-dispatching. */
+ /* This also picks up some anomalous cases of non-packed arrays. */
+ default:
+ {
+ uint index;
+
+ switch (*iref_packed >> r_packed_type_shift) {
+ case pt_full_ref:
+ case pt_full_ref + 1:
+ INCR(p_full);
+ if (iosp >= ostop)
+ return_with_stackoverflow_iref();
+ /* We know this can't be an executable object */
+ /* requiring special handling, so we just push it. */
+ ++iosp;
+ /* We know that refs are properly aligned: */
+ /* see packed.h for details. */
+ ref_assign_inline(iosp, IREF);
+ next();
+ case pt_executable_operator:
+ index = *iref_packed & packed_value_mask;
+ if (--ticks_left <= 0) { /* The following doesn't work, */
+ /* and I can't figure out why. */
/****** goto sst_short; ******/
- }
- if (!op_index_is_operator(index)) {
- INCR(p_exec_oparray);
- store_state_short(iesp);
- opindex = index;
- /* Call the operator procedure. */
- index -= op_def_count;
- pvalue = (const ref *)
- (index < r_size(&i_ctx_p->op_array_table_global.table) ?
- i_ctx_p->op_array_table_global.table.value.const_refs +
- index :
- i_ctx_p->op_array_table_local.table.value.const_refs +
- (index - r_size(&i_ctx_p->op_array_table_global.table)));
- goto oppr;
- }
- INCR(p_exec_operator);
- /* See the main plain_exec(t_operator) case */
- /* for details of what happens here. */
+ }
+ if (!op_index_is_operator(index)) {
+ INCR(p_exec_oparray);
+ store_state_short(iesp);
+ opindex = index;
+ /* Call the operator procedure. */
+ index -= op_def_count;
+ pvalue = (const ref *)
+ (index < r_size(&i_ctx_p->op_array_table_global.table) ?
+ i_ctx_p->op_array_table_global.table.value.const_refs +
+ index :
+ i_ctx_p->op_array_table_local.table.value.const_refs +
+ (index - r_size(&i_ctx_p->op_array_table_global.table)));
+ goto oppr;
+ }
+ INCR(p_exec_operator);
+ /* See the main plain_exec(t_operator) case */
+ /* for details of what happens here. */
#if PACKED_SPECIAL_OPS
- /*
- * We arranged in iinit.c that the special ops
- * have operator indices starting at 1.
- *
- * The (int) cast in the next line is required
- * because some compilers don't allow arithmetic
- * involving two different enumerated types.
- */
+ /*
+ * We arranged in iinit.c that the special ops
+ * have operator indices starting at 1.
+ *
+ * The (int) cast in the next line is required
+ * because some compilers don't allow arithmetic
+ * involving two different enumerated types.
+ */
# define case_xop(xop) case xop - (int)tx_op + 1
- switch (index) {
- case_xop(tx_op_add):goto x_add;
- case_xop(tx_op_def):goto x_def;
- case_xop(tx_op_dup):goto x_dup;
- case_xop(tx_op_exch):goto x_exch;
- case_xop(tx_op_if):goto x_if;
- case_xop(tx_op_ifelse):goto x_ifelse;
- case_xop(tx_op_index):goto x_index;
- case_xop(tx_op_pop):goto x_pop;
- case_xop(tx_op_roll):goto x_roll;
- case_xop(tx_op_sub):goto x_sub;
- case 0: /* for dumb compilers */
- default:
- ;
- }
+ switch (index) {
+ case_xop(tx_op_add):goto x_add;
+ case_xop(tx_op_def):goto x_def;
+ case_xop(tx_op_dup):goto x_dup;
+ case_xop(tx_op_exch):goto x_exch;
+ case_xop(tx_op_if):goto x_if;
+ case_xop(tx_op_ifelse):goto x_ifelse;
+ case_xop(tx_op_index):goto x_index;
+ case_xop(tx_op_pop):goto x_pop;
+ case_xop(tx_op_roll):goto x_roll;
+ case_xop(tx_op_sub):goto x_sub;
+ case 0: /* for dumb compilers */
+ default:
+ ;
+ }
# undef case_xop
#endif
- INCR(p_exec_non_x_operator);
- esp = iesp;
- osp = iosp;
- switch (code = call_operator(op_index_proc(index), i_ctx_p)) {
- case 0:
- case 1:
- iosp = osp;
- next_short();
- case o_push_estack:
- store_state_short(iesp);
- goto opush;
- case o_pop_estack:
- iosp = osp;
- if (esp == iesp) {
- next_short();
- }
- iesp = esp;
- goto up;
- case o_reschedule:
- store_state_short(iesp);
- goto res;
- case e_RemapColor:
- store_state_short(iesp);
- goto remap;
- }
- iosp = osp;
- iesp = esp;
- return_with_code_iref();
- case pt_integer:
- INCR(p_integer);
- if (iosp >= ostop)
- return_with_stackoverflow_iref();
- ++iosp;
- make_int(iosp,
- ((int)*iref_packed & packed_int_mask) +
- packed_min_intval);
- next_short();
- case pt_literal_name:
- INCR(p_lit_name);
- {
- uint nidx = *iref_packed & packed_value_mask;
-
- if (iosp >= ostop)
- return_with_stackoverflow_iref();
- ++iosp;
- name_index_ref_inline(int_nt, nidx, iosp);
- next_short();
- }
- case pt_executable_name:
- INCR(p_exec_name);
- {
- uint nidx = *iref_packed & packed_value_mask;
-
- pvalue = name_index_ptr_inline(int_nt, nidx)->pvalue;
- if (!pv_valid(pvalue)) {
- uint htemp;
-
- INCR(p_find_name);
- if ((pvalue = dict_find_name_by_index_inline(nidx, htemp)) == 0) {
- names_index_ref(int_nt, nidx, &token);
- return_with_error(e_undefined, &token);
- }
- }
- if (r_has_masked_attrs(pvalue, a_execute, a_execute + a_executable)) { /* Literal, push it. */
- INCR(p_name_lit);
- if (iosp >= ostop)
- return_with_stackoverflow_iref();
- ++iosp;
- ref_assign_inline(iosp, pvalue);
- next_short();
- }
- if (r_is_proc(pvalue)) { /* This is an executable procedure, */
- /* execute it. */
- INCR(p_name_proc);
- store_state_short(iesp);
- goto pr;
- }
- /* Not a literal or procedure, reinterpret it. */
- store_state_short(iesp);
- icount = 0;
- SET_IREF(pvalue);
- goto top;
- }
- /* default can't happen here */
- }
- }
+ INCR(p_exec_non_x_operator);
+ esp = iesp;
+ osp = iosp;
+ switch (code = call_operator(op_index_proc(index), i_ctx_p)) {
+ case 0:
+ case 1:
+ iosp = osp;
+ next_short();
+ case o_push_estack:
+ store_state_short(iesp);
+ goto opush;
+ case o_pop_estack:
+ iosp = osp;
+ if (esp == iesp) {
+ next_short();
+ }
+ iesp = esp;
+ goto up;
+ case o_reschedule:
+ store_state_short(iesp);
+ goto res;
+ case e_RemapColor:
+ store_state_short(iesp);
+ goto remap;
+ }
+ iosp = osp;
+ iesp = esp;
+ return_with_code_iref();
+ case pt_integer:
+ INCR(p_integer);
+ if (iosp >= ostop)
+ return_with_stackoverflow_iref();
+ ++iosp;
+ make_int(iosp,
+ ((int)*iref_packed & packed_int_mask) +
+ packed_min_intval);
+ next_short();
+ case pt_literal_name:
+ INCR(p_lit_name);
+ {
+ uint nidx = *iref_packed & packed_value_mask;
+
+ if (iosp >= ostop)
+ return_with_stackoverflow_iref();
+ ++iosp;
+ name_index_ref_inline(int_nt, nidx, iosp);
+ next_short();
+ }
+ case pt_executable_name:
+ INCR(p_exec_name);
+ {
+ uint nidx = *iref_packed & packed_value_mask;
+
+ pvalue = name_index_ptr_inline(int_nt, nidx)->pvalue;
+ if (!pv_valid(pvalue)) {
+ uint htemp;
+
+ INCR(p_find_name);
+ if ((pvalue = dict_find_name_by_index_inline(nidx, htemp)) == 0) {
+ names_index_ref(int_nt, nidx, &token);
+ return_with_error(e_undefined, &token);
+ }
+ }
+ if (r_has_masked_attrs(pvalue, a_execute, a_execute + a_executable)) { /* Literal, push it. */
+ INCR(p_name_lit);
+ if (iosp >= ostop)
+ return_with_stackoverflow_iref();
+ ++iosp;
+ ref_assign_inline(iosp, pvalue);
+ next_short();
+ }
+ if (r_is_proc(pvalue)) { /* This is an executable procedure, */
+ /* execute it. */
+ INCR(p_name_proc);
+ store_state_short(iesp);
+ goto pr;
+ }
+ /* Not a literal or procedure, reinterpret it. */
+ store_state_short(iesp);
+ icount = 0;
+ SET_IREF(pvalue);
+ goto top;
+ }
+ /* default can't happen here */
+ }
+ }
}
/* Literal type, just push it. */
if (iosp >= ostop)
- return_with_stackoverflow_iref();
+ return_with_stackoverflow_iref();
++iosp;
ref_assign_inline(iosp, IREF);
bot:next();
- out: /* At most 1 more token in the current procedure. */
+ out: /* At most 1 more token in the current procedure. */
/* (We already decremented icount.) */
if (!icount) {
- /* Pop the execution stack for tail recursion. */
- iesp--;
- iref_packed = IREF_NEXT(iref_packed);
- goto top;
+ /* Pop the execution stack for tail recursion. */
+ iesp--;
+ iref_packed = IREF_NEXT(iref_packed);
+ goto top;
}
up:if (--ticks_left < 0)
- goto slice;
+ goto slice;
/* See if there is anything left on the execution stack. */
if (!r_is_proc(iesp)) {
- SET_IREF(iesp--);
- icount = 0;
- goto top;
+ SET_IREF(iesp--);
+ icount = 0;
+ goto top;
}
- SET_IREF(iesp->value.refs); /* next element of array */
+ SET_IREF(iesp->value.refs); /* next element of array */
icount = r_size(iesp) - 1;
- if (icount <= 0) { /* <= 1 more elements */
- iesp--; /* pop, or tail recursion */
- if (icount < 0)
- goto up;
+ if (icount <= 0) { /* <= 1 more elements */
+ iesp--; /* pop, or tail recursion */
+ if (icount < 0)
+ goto up;
}
goto top;
res:
@@ -1643,46 +1643,46 @@ res:
*pi_ctx_p = i_ctx_p;
code = (*i_ctx_p->reschedule_proc)(pi_ctx_p);
i_ctx_p = *pi_ctx_p;
- sched: /* We've just called a scheduling procedure. */
+ sched: /* We've just called a scheduling procedure. */
/* The interpreter state is in memory; iref is not current. */
if (code < 0) {
- set_error(code);
- /*
- * We need a real object to return as the error object.
- * (It only has to last long enough to store in
- * *perror_object.)
- */
- make_null_proc(&ierror.full);
- SET_IREF(ierror.obj = &ierror.full);
- goto error_exit;
+ set_error(code);
+ /*
+ * We need a real object to return as the error object.
+ * (It only has to last long enough to store in
+ * *perror_object.)
+ */
+ make_null_proc(&ierror.full);
+ SET_IREF(ierror.obj = &ierror.full);
+ goto error_exit;
}
/* Reload state information from memory. */
iosp = osp;
iesp = esp;
goto up;
-#if 0 /****** ****** ***** */
- sst: /* Time-slice, but push the current object first. */
+#if 0 /****** ****** ***** */
+ sst: /* Time-slice, but push the current object first. */
store_state(iesp);
if (iesp >= estop)
- return_with_error_iref(e_execstackoverflow);
+ return_with_error_iref(e_execstackoverflow);
iesp++;
ref_assign_inline(iesp, iref);
#endif /****** ****** ***** */
- slice: /* It's time to time-slice or garbage collect. */
+ slice: /* It's time to time-slice or garbage collect. */
/* iref is not live, so we don't need to do a store_state. */
osp = iosp;
esp = iesp;
/* If ticks_left <= -100, we need to GC now. */
- if (ticks_left <= -100) { /* We need to garbage collect now. */
- *pi_ctx_p = i_ctx_p;
- code = interp_reclaim(pi_ctx_p, -1);
- i_ctx_p = *pi_ctx_p;
+ if (ticks_left <= -100) { /* We need to garbage collect now. */
+ *pi_ctx_p = i_ctx_p;
+ code = interp_reclaim(pi_ctx_p, -1);
+ i_ctx_p = *pi_ctx_p;
} else if (i_ctx_p->time_slice_proc != NULL) {
- *pi_ctx_p = i_ctx_p;
- code = (*i_ctx_p->time_slice_proc)(pi_ctx_p);
- i_ctx_p = *pi_ctx_p;
+ *pi_ctx_p = i_ctx_p;
+ code = (*i_ctx_p->time_slice_proc)(pi_ctx_p);
+ i_ctx_p = *pi_ctx_p;
} else
- code = 0;
+ code = 0;
ticks_left = i_ctx_p->time_slice_ticks;
set_code_on_interrupt(imemory, &code);
goto sched;
@@ -1695,38 +1695,38 @@ res:
ierror.obj = IREF;
rwe:
if (!r_is_packed(iref_packed))
- store_state(iesp);
+ store_state(iesp);
else {
- /*
- * We need a real object to return as the error object.
- * (It only has to last long enough to store in *perror_object.)
- */
- packed_get(imemory, (const ref_packed *)ierror.obj, &ierror.full);
- store_state_short(iesp);
- if (IREF == ierror.obj)
- SET_IREF(&ierror.full);
- ierror.obj = &ierror.full;
+ /*
+ * We need a real object to return as the error object.
+ * (It only has to last long enough to store in *perror_object.)
+ */
+ packed_get(imemory, (const ref_packed *)ierror.obj, &ierror.full);
+ store_state_short(iesp);
+ if (IREF == ierror.obj)
+ SET_IREF(&ierror.full);
+ ierror.obj = &ierror.full;
}
error_exit:
- if (ERROR_IS_INTERRUPT(ierror.code)) { /* We must push the current object being interpreted */
- /* back on the e-stack so it will be re-executed. */
- /* Currently, this is always an executable operator, */
- /* but it might be something else someday if we check */
- /* for interrupts in the interpreter loop itself. */
- if (iesp >= estop)
- code = e_execstackoverflow;
- else {
- iesp++;
- ref_assign_inline(iesp, IREF);
- }
+ if (ERROR_IS_INTERRUPT(ierror.code)) { /* We must push the current object being interpreted */
+ /* back on the e-stack so it will be re-executed. */
+ /* Currently, this is always an executable operator, */
+ /* but it might be something else someday if we check */
+ /* for interrupts in the interpreter loop itself. */
+ if (iesp >= estop)
+ code = e_execstackoverflow;
+ else {
+ iesp++;
+ ref_assign_inline(iesp, IREF);
+ }
}
esp = iesp;
osp = iosp;
ref_assign_inline(perror_object, ierror.obj);
#ifdef DEBUG
if (ierror.code == e_InterpreterExit) {
- /* Do not call gs_log_error to reduce the noise. */
- return e_InterpreterExit;
+ /* Do not call gs_log_error to reduce the noise. */
+ return e_InterpreterExit;
}
#endif
return gs_log_error(ierror.code, __FILE__, ierror.line);
@@ -1744,7 +1744,7 @@ oparray_pop(i_ctx_t *i_ctx_p)
/* This procedure is called only from pop_estack. */
static int
oparray_cleanup(i_ctx_t *i_ctx_p)
-{ /* esp points just below the cleanup procedure. */
+{ /* esp points just below the cleanup procedure. */
es_ptr ep = esp;
uint ocount_old = (uint) ep[3].value.intval;
uint dcount_old = (uint) ep[4].value.intval;
@@ -1752,10 +1752,10 @@ oparray_cleanup(i_ctx_t *i_ctx_p)
uint dcount = ref_stack_count(&d_stack);
if (ocount > ocount_old)
- ref_stack_pop(&o_stack, ocount - ocount_old);
+ ref_stack_pop(&o_stack, ocount - ocount_old);
if (dcount > dcount_old) {
- ref_stack_pop(&d_stack, dcount - dcount_old);
- dict_set_top();
+ ref_stack_pop(&d_stack, dcount - dcount_old);
+ dict_set_top();
}
return 0;
}
@@ -1775,11 +1775,11 @@ oparray_find(i_ctx_t *i_ctx_p)
ref *ep;
for (i = 0; (ep = ref_stack_index(&e_stack, i)) != 0; ++i) {
- if (r_is_estack_mark(ep) &&
- (ep->value.opproc == oparray_cleanup ||
- ep->value.opproc == oparray_no_cleanup)
- )
- return ep;
+ if (r_is_estack_mark(ep) &&
+ (ep->value.opproc == oparray_cleanup ||
+ ep->value.opproc == oparray_no_cleanup)
+ )
+ return ep;
}
return 0;
}
@@ -1794,15 +1794,15 @@ zerrorexec(i_ctx_t *i_ctx_p)
int code;
check_op(2);
- check_estack(4); /* mark/cleanup, errobj, pop, obj */
+ check_estack(4); /* mark/cleanup, errobj, pop, obj */
push_mark_estack(es_other, errorexec_cleanup);
*++esp = op[-1];
push_op_estack(errorexec_pop);
code = zexec(i_ctx_p);
if (code >= 0)
- pop(1);
+ pop(1);
else
- esp -= 3; /* undo our additions to estack */
+ esp -= 3; /* undo our additions to estack */
return code;
}
@@ -1817,12 +1817,12 @@ zfinderrorobject(i_ctx_t *i_ctx_p)
ref errobj;
if (errorexec_find(i_ctx_p, &errobj)) {
- push(2);
- op[-1] = errobj;
- make_true(op);
+ push(2);
+ op[-1] = errobj;
+ make_true(op);
} else {
- push(1);
- make_false(op);
+ push(1);
+ make_false(op);
}
return 0;
}
@@ -1839,24 +1839,24 @@ errorexec_find(i_ctx_t *i_ctx_p, ref *perror_object)
const ref *ep;
for (i = 0; (ep = ref_stack_index(&e_stack, i)) != 0; ++i) {
- if (r_is_estack_mark(ep)) {
- if (ep->value.opproc == oparray_cleanup) {
- /* See oppr: above. */
- uint opindex = (uint)ep[1].value.intval;
- if (opindex == 0) /* internal operator, ignore */
- continue;
- op_index_ref(imemory, opindex, perror_object);
- return 1;
- }
- if (ep->value.opproc == oparray_no_cleanup)
- return 0; /* protection disabled */
- if (ep->value.opproc == errorexec_cleanup) {
- if (r_has_type(ep + 1, t_null))
- return 0;
- *perror_object = ep[1]; /* see .errorexec above */
- return 1;
- }
- }
+ if (r_is_estack_mark(ep)) {
+ if (ep->value.opproc == oparray_cleanup) {
+ /* See oppr: above. */
+ uint opindex = (uint)ep[1].value.intval;
+ if (opindex == 0) /* internal operator, ignore */
+ continue;
+ op_index_ref(imemory, opindex, perror_object);
+ return 1;
+ }
+ if (ep->value.opproc == oparray_no_cleanup)
+ return 0; /* protection disabled */
+ if (ep->value.opproc == errorexec_cleanup) {
+ if (r_has_type(ep + 1, t_null))
+ return 0;
+ *perror_object = ep[1]; /* see .errorexec above */
+ return 1;
+ }
+ }
}
return 0;
}
@@ -1886,9 +1886,9 @@ zsetstackprotect(i_ctx_t *i_ctx_p)
check_type(*op, t_boolean);
if (ep == 0)
- return_error(e_rangecheck);
+ return_error(e_rangecheck);
ep->value.opproc =
- (op->value.boolval ? oparray_cleanup : oparray_no_cleanup);
+ (op->value.boolval ? oparray_cleanup : oparray_no_cleanup);
pop(1);
return 0;
}
@@ -1902,7 +1902,7 @@ zcurrentstackprotect(i_ctx_t *i_ctx_p)
ref *ep = oparray_find(i_ctx_p);
if (ep == 0)
- return_error(e_rangecheck);
+ return_error(e_rangecheck);
push(1);
make_bool(op, ep->value.opproc == oparray_cleanup);
return 0;