Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/psi/interp.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2021 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14
*/
15
16
17
/* Ghostscript language interpreter */
18
#include "memory_.h"
19
#include "string_.h"
20
#include "ghost.h"
21
#include "gsstruct.h"           /* for iastruct.h */
22
#include "gserrors.h"           /* for gpcheck.h */
23
#include "stream.h"
24
#include "ierrors.h"
25
#include "estack.h"
26
#include "ialloc.h"
27
#include "iastruct.h"
28
#include "icontext.h"
29
#include "icremap.h"
30
#include "idebug.h"
31
#include "igstate.h"            /* for handling gs_error_Remap_Color */
32
#include "inamedef.h"
33
#include "iname.h"              /* for the_name_table */
34
#include "interp.h"
35
#include "ipacked.h"
36
#include "ostack.h"             /* must precede iscan.h */
37
#include "strimpl.h"            /* for sfilter.h */
38
#include "sfilter.h"            /* for iscan.h */
39
#include "iscan.h"
40
#include "iddict.h"
41
#include "isave.h"
42
#include "istack.h"
43
#include "itoken.h"
44
#include "iutil.h"              /* for array_get */
45
#include "ivmspace.h"
46
#include "iinit.h"
47
#include "dstack.h"
48
#include "files.h"              /* for file_check_read */
49
#include "oper.h"
50
#include "store.h"
51
#include "gpcheck.h"
52
53
/*
54
 * We may or may not optimize the handling of the special fast operators
55
 * in packed arrays.  If we do this, they run much faster when packed, but
56
 * slightly slower when not packed.
57
 */
58
#define PACKED_SPECIAL_OPS 1
59
60
/*
61
 * Pseudo-operators (procedures of type t_oparray) record
62
 * the operand and dictionary stack pointers, and restore them if an error
63
 * occurs during the execution of the procedure and if the procedure hasn't
64
 * (net) decreased the depth of the stack.  While this obviously doesn't
65
 * do all the work of restoring the state if a pseudo-operator gets an
66
 * error, it's a big help.  The only downside is that pseudo-operators run
67
 * a little slower.
68
 */
69
70
/* GC descriptors for stacks */
71
extern_st(st_ref_stack);
72
public_st_dict_stack();
73
public_st_exec_stack();
74
public_st_op_stack();
75
76
/*
77
 * Apply an operator.  When debugging, we route all operator calls
78
 * through a procedure.
79
 */
80
#if defined(DEBUG_TRACE_PS_OPERATORS) || defined(DEBUG)
81
#define call_operator(proc, p) (*call_operator_fn)(proc, p)
82
static int
83
do_call_operator(op_proc_t op_proc, i_ctx_t *i_ctx_p)
84
{
85
    int code;
86
    code = op_proc(i_ctx_p);
87
    if (gs_debug_c(gs_debug_flag_validate_clumps))
88
        ivalidate_clean_spaces(i_ctx_p);
89
    return code; /* A good place for a conditional breakpoint. */
90
}
91
static int
92
do_call_operator_verbose(op_proc_t op_proc, i_ctx_t *i_ctx_p)
93
{
94
    int code;
95
96
#ifndef SHOW_STACK_DEPTHS
97
    if_debug1m('!', imemory, "[!]operator %s\n", op_get_name_string(op_proc));
98
#else
99
    if_debug3m('!', imemory, "[!][es=%d os=%d]operator %s\n",
100
            esp-i_ctx_p->exec_stack.stack.bot,
101
            osp-i_ctx_p->op_stack.stack.bot,
102
            op_get_name_string(op_proc));
103
#endif
104
    code = do_call_operator(op_proc, i_ctx_p);
105
#if defined(SHOW_STACK_DEPTHS)
106
    if_debug2m('!', imemory, "[!][es=%d os=%d]\n",
107
            esp-i_ctx_p->exec_stack.stack.bot,
108
            osp-i_ctx_p->op_stack.stack.bot);
109
#endif
110
    if (gs_debug_c(gs_debug_flag_validate_clumps))
111
        ivalidate_clean_spaces(i_ctx_p);
112
    return code; /* A good place for a conditional breakpoint. */
113
}
114
#else
115
19.0G
#  define call_operator(proc, p) ((*(proc))(p))
116
#endif
117
118
/* Define debugging statistics (not threadsafe as uses globals) */
119
/* #define COLLECT_STATS_IDSTACK */
120
121
#ifdef COLLECT_STATS_INTERP
122
struct stats_interp_s {
123
    long top;
124
    long lit, lit_array, exec_array, exec_operator, exec_name;
125
    long x_add, x_def, x_dup, x_exch, x_if, x_ifelse,
126
        x_index, x_pop, x_roll, x_sub;
127
    long find_name, name_lit, name_proc, name_oparray, name_operator;
128
    long p_full, p_exec_operator, p_exec_oparray, p_exec_non_x_operator,
129
        p_integer, p_lit_name, p_exec_name;
130
    long p_find_name, p_name_lit, p_name_proc;
131
} stats_interp;
132
# define INCR(v) (++(stats_interp.v))
133
#else
134
165G
# define INCR(v) DO_NOTHING
135
#endif
136
137
/* Forward references */
138
static int estack_underflow(i_ctx_t *);
139
static int interp(i_ctx_t **, const ref *, ref *);
140
static int interp_exit(i_ctx_t *);
141
static int zforceinterp_exit(i_ctx_t *i_ctx_p);
142
static void set_gc_signal(i_ctx_t *, int);
143
static int copy_stack(i_ctx_t *, const ref_stack_t *, int skip, ref *);
144
static int oparray_pop(i_ctx_t *);
145
static int oparray_cleanup(i_ctx_t *);
146
static int zerrorexec(i_ctx_t *);
147
static int zfinderrorobject(i_ctx_t *);
148
static int errorexec_pop(i_ctx_t *);
149
static int errorexec_cleanup(i_ctx_t *);
150
static int zsetstackprotect(i_ctx_t *);
151
static int zcurrentstackprotect(i_ctx_t *);
152
static int zactonuel(i_ctx_t *);
153
154
/* Stack sizes */
155
156
/* The maximum stack sizes may all be set in the makefile. */
157
158
/*
159
 * Define the initial maximum size of the operand stack (MaxOpStack
160
 * user parameter).
161
 */
162
#ifndef MAX_OSTACK
163
89.2k
#  define MAX_OSTACK 800
164
#endif
165
/*
166
 * The minimum block size for extending the operand stack is the larger of:
167
 *      - the maximum number of parameters to an operator
168
 *      (currently setcolorscreen, with 12 parameters);
169
 *      - the maximum number of values pushed by an operator
170
 *      (currently setcolortransfer, which calls zcolor_remap_one 4 times
171
 *      and therefore pushes 16 values).
172
 */
173
#define MIN_BLOCK_OSTACK 16
174
const int gs_interp_max_op_num_args = MIN_BLOCK_OSTACK;         /* for iinit.c */
175
176
/*
177
 * Define the initial maximum size of the execution stack (MaxExecStack
178
 * user parameter).
179
 */
180
#ifndef MAX_ESTACK
181
89.2k
#  define MAX_ESTACK 5000
182
#endif
183
/*
184
 * The minimum block size for extending the execution stack is the largest
185
 * size of a contiguous block surrounding an e-stack mark.  (At least,
186
 * that's what the minimum value would be if we supported multi-block
187
 * estacks, which we currently don't.)  Currently, the largest such block is
188
 * the one created for text processing, which is 8 (snumpush) slots.
189
 */
190
32
#define MIN_BLOCK_ESTACK 8
191
/*
192
 * If we get an e-stack overflow, we need to cut it back far enough to
193
 * have some headroom for executing the error procedure.
194
 */
195
8
#define ES_HEADROOM 20
196
197
/*
198
 * Define the initial maximum size of the dictionary stack (MaxDictStack
199
 * user parameter).  Again, this is also currently the block size for
200
 * extending the d-stack.
201
 */
202
#ifndef MAX_DSTACK
203
89.2k
#  define MAX_DSTACK 20
204
#endif
205
/*
206
 * The minimum block size for extending the dictionary stack is the number
207
 * of permanent entries on the dictionary stack, currently 3.
208
 */
209
#define MIN_BLOCK_DSTACK 3
210
211
/* See estack.h for a description of the execution stack. */
212
213
/* The logic for managing icount and iref below assumes that */
214
/* there are no control operators which pop and then push */
215
/* information on the execution stack. */
216
217
/* Stacks */
218
extern_st(st_ref_stack);
219
267k
#define OS_GUARD_UNDER 10
220
267k
#define OS_GUARD_OVER 10
221
#define OS_REFS_SIZE(body_size)\
222
178k
  (stack_block_refs + OS_GUARD_UNDER + (body_size) + OS_GUARD_OVER)
223
224
267k
#define ES_GUARD_UNDER 1
225
267k
#define ES_GUARD_OVER 10
226
#define ES_REFS_SIZE(body_size)\
227
178k
  (stack_block_refs + ES_GUARD_UNDER + (body_size) + ES_GUARD_OVER)
228
229
#define DS_REFS_SIZE(body_size)\
230
89.2k
  (stack_block_refs + (body_size))
231
232
/* Extended types.  The interpreter may replace the type of operators */
233
/* in procedures with these, to speed up the interpretation loop. */
234
/****** NOTE: If you add or change entries in this list, */
235
/****** you must change the three dispatches in the interpreter loop. */
236
/* The operator procedures are declared in opextern.h. */
237
12.7G
#define tx_op t_next_index
238
typedef enum {
239
    tx_op_add = tx_op,
240
    tx_op_def,
241
    tx_op_dup,
242
    tx_op_exch,
243
    tx_op_if,
244
    tx_op_ifelse,
245
    tx_op_index,
246
    tx_op_pop,
247
    tx_op_roll,
248
    tx_op_sub,
249
    tx_next_op
250
} special_op_types;
251
252
63.7M
#define num_special_ops ((int)tx_next_op - tx_op)
253
const int gs_interp_num_special_ops = num_special_ops;  /* for iinit.c */
254
const int tx_next_index = tx_next_op;
255
256
/*
257
 * NOTE: if the size of either table below ever exceeds 15 real entries, it
258
 * will have to be split.
259
 */
260
/* Define the extended-type operators per the list above. */
261
const op_def interp1_op_defs[] = {
262
    /*
263
     * The very first entry, which corresponds to operator index 0,
264
     * must not contain an actual operator.
265
     */
266
    op_def_begin_dict("systemdict"),
267
    {"2add", zadd},
268
    {"2def", zdef},
269
    {"1dup", zdup},
270
    {"2exch", zexch},
271
    {"2if", zif},
272
    {"3ifelse", zifelse},
273
    {"1index", zindex},
274
    {"1pop", zpop},
275
    {"2roll", zroll},
276
    {"2sub", zsub},
277
    op_def_end(0)
278
};
279
/* Define the internal interpreter operators. */
280
const op_def interp2_op_defs[] = {
281
    {"0.currentstackprotect", zcurrentstackprotect},
282
    {"1.setstackprotect", zsetstackprotect},
283
    {"2.errorexec", zerrorexec},
284
    {"0.finderrorobject", zfinderrorobject},
285
    {"0%interp_exit", interp_exit},
286
    {"0.forceinterp_exit", zforceinterp_exit},
287
    {"0%oparray_pop", oparray_pop},
288
    {"0%errorexec_pop", errorexec_pop},
289
    {"0.actonuel", zactonuel},
290
    op_def_end(0)
291
};
292
293
#define make_null_proc(pref)\
294
244
  make_empty_const_array(pref, a_executable + a_readonly)
295
296
/* Initialize the interpreter. */
297
int
298
gs_interp_init(i_ctx_t **pi_ctx_p, const ref *psystem_dict,
299
               gs_dual_memory_t *dmem)
300
89.2k
{
301
    /* Create and initialize a context state. */
302
89.2k
    gs_context_state_t *pcst = 0;
303
89.2k
    int code = context_state_alloc(&pcst, psystem_dict, dmem);
304
89.2k
    if (code >= 0) {
305
89.2k
        code = context_state_load(pcst);
306
89.2k
        if (code < 0) {
307
0
            context_state_free(pcst);
308
0
            pcst = NULL;
309
0
        }
310
89.2k
    }
311
312
89.2k
    if (code < 0)
313
0
        lprintf1("Fatal error %d in gs_interp_init!\n", code);
314
89.2k
    *pi_ctx_p = pcst;
315
316
89.2k
    return code;
317
89.2k
}
318
/*
319
 * Create initial stacks for the interpreter.
320
 * We export this for creating new contexts.
321
 */
322
int
323
gs_interp_alloc_stacks(gs_ref_memory_t *mem, gs_context_state_t * pcst)
324
89.2k
{
325
89.2k
    int code;
326
89.2k
    gs_ref_memory_t *smem =
327
89.2k
        (gs_ref_memory_t *)gs_memory_stable((gs_memory_t *)mem);
328
89.2k
    ref stk;
329
330
178k
#define REFS_SIZE_OSTACK OS_REFS_SIZE(MAX_OSTACK)
331
178k
#define REFS_SIZE_ESTACK ES_REFS_SIZE(MAX_ESTACK)
332
89.2k
#define REFS_SIZE_DSTACK DS_REFS_SIZE(MAX_DSTACK)
333
89.2k
    code = gs_alloc_ref_array(smem, &stk, 0,
334
89.2k
                       REFS_SIZE_OSTACK + REFS_SIZE_ESTACK +
335
89.2k
                       REFS_SIZE_DSTACK, "gs_interp_alloc_stacks");
336
89.2k
    if (code < 0)
337
0
        return code;
338
339
89.2k
    {
340
89.2k
        ref_stack_t *pos = &pcst->op_stack.stack;
341
342
89.2k
        r_set_size(&stk, REFS_SIZE_OSTACK);
343
89.2k
        code = ref_stack_init(pos, &stk, OS_GUARD_UNDER, OS_GUARD_OVER, NULL,
344
89.2k
                              smem, NULL);
345
89.2k
  if (code < 0)
346
0
            return code;
347
89.2k
        ref_stack_set_error_codes(pos, gs_error_stackunderflow, gs_error_stackoverflow);
348
89.2k
        ref_stack_set_max_count(pos, MAX_OSTACK);
349
89.2k
        stk.value.refs += REFS_SIZE_OSTACK;
350
89.2k
    }
351
352
0
    {
353
89.2k
        ref_stack_t *pes = &pcst->exec_stack.stack;
354
89.2k
        ref euop;
355
356
89.2k
        r_set_size(&stk, REFS_SIZE_ESTACK);
357
89.2k
        make_oper(&euop, 0, estack_underflow);
358
89.2k
        code = ref_stack_init(pes, &stk, ES_GUARD_UNDER, ES_GUARD_OVER, &euop,
359
89.2k
                       smem, NULL);
360
89.2k
  if (code < 0)
361
0
            return code;
362
89.2k
        ref_stack_set_error_codes(pes, gs_error_ExecStackUnderflow,
363
89.2k
                                  gs_error_execstackoverflow);
364
        /**************** E-STACK EXPANSION IS NYI. ****************/
365
89.2k
        ref_stack_allow_expansion(pes, false);
366
89.2k
        ref_stack_set_max_count(pes, MAX_ESTACK);
367
89.2k
        stk.value.refs += REFS_SIZE_ESTACK;
368
89.2k
    }
369
370
0
    {
371
89.2k
        ref_stack_t *pds = &pcst->dict_stack.stack;
372
373
89.2k
        r_set_size(&stk, REFS_SIZE_DSTACK);
374
89.2k
        code = ref_stack_init(pds, &stk, 0, 0, NULL, smem, NULL);
375
89.2k
        if (code < 0)
376
0
            return code;
377
89.2k
        ref_stack_set_error_codes(pds, gs_error_dictstackunderflow,
378
89.2k
                                  gs_error_dictstackoverflow);
379
89.2k
        ref_stack_set_max_count(pds, MAX_DSTACK);
380
89.2k
    }
381
382
0
#undef REFS_SIZE_OSTACK
383
0
#undef REFS_SIZE_ESTACK
384
0
#undef REFS_SIZE_DSTACK
385
0
    return 0;
386
89.2k
}
387
/*
388
 * Free the stacks when destroying a context.  This is the inverse of
389
 * create_stacks.
390
 */
391
void
392
gs_interp_free_stacks(gs_ref_memory_t * smem, gs_context_state_t * pcst)
393
0
{
394
    /* Free the stacks in inverse order of allocation. */
395
0
    ref_stack_release(&pcst->dict_stack.stack);
396
0
    ref_stack_release(&pcst->exec_stack.stack);
397
0
    ref_stack_release(&pcst->op_stack.stack);
398
0
}
399
void
400
gs_interp_reset(i_ctx_t *i_ctx_p)
401
89.2k
{   /* Reset the stacks. */
402
89.2k
    ref_stack_clear(&o_stack);
403
89.2k
    ref_stack_clear(&e_stack);
404
89.2k
    esp++;
405
89.2k
    make_oper(esp, 0, interp_exit);
406
89.2k
    ref_stack_pop_to(&d_stack, min_dstack_size);
407
89.2k
    dict_set_top();
408
89.2k
}
409
/* Report an e-stack block underflow.  The bottom guard slots of */
410
/* e-stack blocks contain a pointer to this procedure. */
411
static int
412
estack_underflow(i_ctx_t *i_ctx_p)
413
0
{
414
0
    return gs_error_ExecStackUnderflow;
415
0
}
416
417
/*
418
 * Create an operator during initialization.
419
 * If operator is hard-coded into the interpreter,
420
 * assign it a special type and index.
421
 */
422
void
423
gs_interp_make_oper(ref * opref, op_proc_t proc, int idx)
424
63.7M
{
425
63.7M
    int i;
426
427
691M
    for (i = num_special_ops; i > 0 && proc != interp1_op_defs[i].proc; --i)
428
627M
        DO_NOTHING;
429
63.7M
    if (i > 0)
430
1.78M
        make_tasv(opref, tx_op + (i - 1), a_executable, i, opproc, proc);
431
61.9M
    else
432
61.9M
        make_tasv(opref, t_operator, a_executable, idx, opproc, proc);
433
63.7M
}
434
435
/*
436
 * Call the garbage collector, updating the context pointer properly.
437
 */
438
int
439
interp_reclaim(i_ctx_t **pi_ctx_p, int space)
440
182k
{
441
182k
    i_ctx_t *i_ctx_p = *pi_ctx_p;
442
182k
    gs_gc_root_t ctx_root, *r = &ctx_root;
443
182k
    int code;
444
445
#ifdef DEBUG
446
    if (gs_debug_c(gs_debug_flag_gc_disable))
447
        return 0;
448
#endif
449
450
182k
    gs_register_struct_root(imemory_system, &r,
451
182k
                            (void **)pi_ctx_p, "interp_reclaim(pi_ctx_p)");
452
182k
    code = (*idmemory->reclaim)(idmemory, space);
453
182k
    i_ctx_p = *pi_ctx_p;        /* may have moved */
454
182k
    gs_unregister_root(imemory_system, r, "interp_reclaim(pi_ctx_p)");
455
182k
    return code;
456
182k
}
457
458
/*
459
 * Invoke the interpreter.  If execution completes normally, return 0.
460
 * If an error occurs, the action depends on user_errors as follows:
461
 *    user_errors < 0: always return an error code.
462
 *    user_errors >= 0: let the PostScript machinery handle all errors.
463
 *      (This will eventually result in a fatal error if no 'stopped'
464
 *      is active.)
465
 * In case of a quit or a fatal error, also store the exit code.
466
 * Set *perror_object to null or the error object.
467
 */
468
static int gs_call_interp(i_ctx_t **, ref *, int, int *, ref *);
469
int
470
gs_interpret(i_ctx_t **pi_ctx_p, ref * pref, int user_errors, int *pexit_code,
471
             ref * perror_object)
472
1.33M
{
473
1.33M
    i_ctx_t *i_ctx_p = *pi_ctx_p;
474
1.33M
    gs_gc_root_t error_root, *r = &error_root;
475
1.33M
    int code;
476
477
1.33M
    gs_register_ref_root(imemory_system, &r,
478
1.33M
                         (void **)&perror_object, "gs_interpret");
479
1.33M
    code = gs_call_interp(pi_ctx_p, pref, user_errors, pexit_code,
480
1.33M
                          perror_object);
481
1.33M
    i_ctx_p = *pi_ctx_p;
482
1.33M
    gs_unregister_root(imemory_system, &error_root, "gs_interpret");
483
    /* Avoid a dangling reference to the lib context GC signal. */
484
1.33M
    set_gc_signal(i_ctx_p, 0);
485
1.33M
    return code;
486
1.33M
}
487
static int
488
gs_call_interp(i_ctx_t **pi_ctx_p, ref * pref, int user_errors,
489
               int *pexit_code, ref * perror_object)
490
1.33M
{
491
1.33M
    ref *epref = pref;
492
1.33M
    ref doref;
493
1.33M
    ref *perrordict;
494
1.33M
    ref error_name;
495
1.33M
    int code, ccode;
496
1.33M
    ref saref;
497
1.33M
    i_ctx_t *i_ctx_p = *pi_ctx_p;
498
1.33M
    int *gc_signal = &imemory_system->gs_lib_ctx->gcsignal;
499
500
1.33M
    *pexit_code = 0;
501
1.33M
    *gc_signal = 0;
502
1.33M
    ialloc_reset_requested(idmemory);
503
52.3M
again:
504
    /* Avoid a dangling error object that might get traced by a future GC. */
505
52.3M
    make_null(perror_object);
506
52.3M
    o_stack.requested = e_stack.requested = d_stack.requested = 0;
507
52.3M
    while (*gc_signal) { /* Some routine below triggered a GC. */
508
0
        gs_gc_root_t epref_root, *r = &epref_root;
509
510
0
        *gc_signal = 0;
511
        /* Make sure that doref will get relocated properly if */
512
        /* a garbage collection happens with epref == &doref. */
513
0
        gs_register_ref_root(imemory_system, &r,
514
0
                             (void **)&epref, "gs_call_interp(epref)");
515
0
        code = interp_reclaim(pi_ctx_p, -1);
516
0
        i_ctx_p = *pi_ctx_p;
517
0
        gs_unregister_root(imemory_system, &epref_root,
518
0
                           "gs_call_interp(epref)");
519
0
        if (code < 0)
520
0
            return code;
521
0
    }
522
52.3M
    code = interp(pi_ctx_p, epref, perror_object);
523
52.3M
    i_ctx_p = *pi_ctx_p;
524
52.3M
    if (!r_has_type(&i_ctx_p->error_object, t__invalid)) {
525
260
        *perror_object = i_ctx_p->error_object;
526
260
        make_t(&i_ctx_p->error_object, t__invalid);
527
260
    }
528
    /* Prevent a dangling reference to the GC signal in ticks_left */
529
    /* in the frame of interp, but be prepared to do a GC if */
530
    /* an allocation in this routine asks for it. */
531
52.3M
    *gc_signal = 0;
532
52.3M
    set_gc_signal(i_ctx_p, 1);
533
52.3M
    if (esp < esbot)            /* popped guard entry */
534
232k
        esp = esbot;
535
52.3M
    switch (code) {
536
6
        case gs_error_Fatal:
537
6
            *pexit_code = 255;
538
6
            return code;
539
302k
        case gs_error_Quit:
540
302k
            *perror_object = osp[-1];
541
302k
            *pexit_code = code = osp->value.intval;
542
302k
            osp -= 2;
543
302k
            return
544
302k
                (code == 0 ? gs_error_Quit :
545
302k
                 code < 0 && code > -100 ? code : gs_error_Fatal);
546
232k
        case gs_error_InterpreterExit:
547
232k
            return 0;
548
0
        case gs_error_ExecStackUnderflow:
549
/****** WRONG -- must keep mark blocks intact ******/
550
0
            ref_stack_pop_block(&e_stack);
551
0
            doref = *perror_object;
552
0
            epref = &doref;
553
0
            goto again;
554
89.2k
        case gs_error_VMreclaim:
555
            /* Do the GC and continue. */
556
            /* We ignore the return value here, if it fails here
557
             * we'll call it again having jumped to the "again" label.
558
             * Where, assuming it fails again, we'll handle the error.
559
             */
560
89.2k
            (void)interp_reclaim(pi_ctx_p,
561
89.2k
                                  (osp->value.intval == 2 ?
562
89.2k
                                   avm_global : avm_local));
563
89.2k
            i_ctx_p = *pi_ctx_p;
564
89.2k
            make_oper(&doref, 0, zpop);
565
89.2k
            epref = &doref;
566
89.2k
            goto again;
567
803k
        case gs_error_NeedInput:
568
803k
        case gs_error_interrupt:
569
803k
            return code;
570
52.3M
    }
571
    /* Adjust osp in case of operand stack underflow */
572
50.9M
    if (osp < osbot - 1)
573
0
        osp = osbot - 1;
574
    /* We have to handle stack over/underflow specially, because */
575
    /* we might be able to recover by adding or removing a block. */
576
50.9M
    switch (code) {
577
0
        case gs_error_dictstackoverflow:
578
            /* We don't have to handle this specially: */
579
            /* The only places that could generate it */
580
            /* use check_dstack, which does a ref_stack_extend, */
581
            /* so if` we get this error, it's a real one. */
582
0
            if (osp >= ostop) {
583
0
                if ((ccode = ref_stack_extend(&o_stack, 1)) < 0)
584
0
                    return ccode;
585
0
            }
586
            /* Skip system dictionaries for CET 20-02-02 */
587
0
            ccode = copy_stack(i_ctx_p, &d_stack, min_dstack_size, &saref);
588
0
            if (ccode < 0)
589
0
                return ccode;
590
0
            ref_stack_pop_to(&d_stack, min_dstack_size);
591
0
            dict_set_top();
592
0
            *++osp = saref;
593
0
            break;
594
25
        case gs_error_dictstackunderflow:
595
25
            if (ref_stack_pop_block(&d_stack) >= 0) {
596
0
                dict_set_top();
597
0
                doref = *perror_object;
598
0
                epref = &doref;
599
0
                goto again;
600
0
            }
601
25
            break;
602
25
        case gs_error_execstackoverflow:
603
            /* We don't have to handle this specially: */
604
            /* The only places that could generate it */
605
            /* use check_estack, which does a ref_stack_extend, */
606
            /* so if we get this error, it's a real one. */
607
8
            if (osp >= ostop) {
608
0
                if ((ccode = ref_stack_extend(&o_stack, 1)) < 0)
609
0
                    return ccode;
610
0
            }
611
8
            ccode = copy_stack(i_ctx_p, &e_stack, 0, &saref);
612
8
            if (ccode < 0)
613
0
                return ccode;
614
8
            {
615
8
                uint count = ref_stack_count(&e_stack);
616
8
                uint limit = ref_stack_max_count(&e_stack) - ES_HEADROOM;
617
618
8
                if (count > limit) {
619
                    /*
620
                     * If there is an e-stack mark within MIN_BLOCK_ESTACK of
621
                     * the new top, cut the stack back to remove the mark.
622
                     */
623
8
                    int skip = count - limit;
624
8
                    int i;
625
626
32
                    for (i = skip; i < skip + MIN_BLOCK_ESTACK; ++i) {
627
31
                        const ref *ep = ref_stack_index(&e_stack, i);
628
629
31
                        if (r_has_type_attrs(ep, t_null, a_executable)) {
630
7
                            skip = i + 1;
631
7
                            break;
632
7
                        }
633
31
                    }
634
8
                    pop_estack(i_ctx_p, skip);
635
8
                }
636
8
            }
637
8
            *++osp = saref;
638
8
            break;
639
2.66M
        case gs_error_stackoverflow:
640
2.66M
            if (ref_stack_extend(&o_stack, o_stack.requested) >= 0) {   /* We can't just re-execute the object, because */
641
                /* it might be a procedure being pushed as a */
642
                /* literal.  We check for this case specially. */
643
2.66M
                doref = *perror_object;
644
2.66M
                if (r_is_proc(&doref)) {
645
244
                    *++osp = doref;
646
244
                    make_null_proc(&doref);
647
244
                }
648
2.66M
                epref = &doref;
649
2.66M
                goto again;
650
2.66M
            }
651
18
            ccode = copy_stack(i_ctx_p, &o_stack, 0, &saref);
652
18
            if (ccode < 0)
653
0
                return ccode;
654
18
            ref_stack_clear(&o_stack);
655
18
            *++osp = saref;
656
18
            break;
657
12.7k
        case gs_error_stackunderflow:
658
12.7k
            if (ref_stack_pop_block(&o_stack) >= 0) {
659
10.2k
                doref = *perror_object;
660
10.2k
                epref = &doref;
661
10.2k
                goto again;
662
10.2k
            }
663
2.51k
            break;
664
50.9M
    }
665
48.2M
    if (user_errors < 0)
666
0
        return code;
667
48.2M
    if (gs_errorname(i_ctx_p, code, &error_name) < 0)
668
0
        return code;            /* out-of-range error code! */
669
670
    /*  We refer to gserrordict first, which is not accessible to Postcript jobs
671
     *  If we're running with SAFERERRORS all the handlers are copied to gserrordict
672
     *  so we'll always find the default one. If not SAFERERRORS, only gs specific
673
     *  errors are in gserrordict.
674
     */
675
48.2M
    if ((dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
676
48.2M
        !r_has_type(perrordict, t_dictionary)                          ||
677
48.2M
        dict_find(perrordict, &error_name, &epref) <= 0)               &&
678
48.2M
       (dict_find_string(systemdict, "errordict", &perrordict) <= 0    ||
679
48.2M
        !r_has_type(perrordict, t_dictionary)                          ||
680
48.2M
        dict_find(perrordict, &error_name, &epref) <= 0))
681
0
        return code;            /* error name not in errordict??? */
682
683
48.2M
    doref = *epref;
684
48.2M
    epref = &doref;
685
    /* Push the error object on the operand stack if appropriate. */
686
48.2M
    if (!GS_ERROR_IS_INTERRUPT(code)) {
687
48.2M
        byte buf[260], *bufptr;
688
48.2M
        uint rlen;
689
        /* Replace the error object if within an oparray or .errorexec. */
690
48.2M
        osp++;
691
48.2M
        if (osp >= ostop) {
692
11
            *pexit_code = gs_error_Fatal;
693
11
            return_error(gs_error_Fatal);
694
11
        }
695
48.2M
        *osp = *perror_object;
696
48.2M
        errorexec_find(i_ctx_p, osp);
697
698
48.2M
        if (!r_has_type(osp, t_string) && !r_has_type(osp, t_name)) {
699
47.7M
            code = obj_cvs(imemory, osp, buf + 2, 256, &rlen, (const byte **)&bufptr);
700
47.7M
            if (code < 0) {
701
0
                const char *unknownstr = "--unknown--";
702
0
                rlen = strlen(unknownstr);
703
0
                memcpy(buf, unknownstr, rlen);
704
0
                bufptr = buf;
705
0
            }
706
47.7M
            else {
707
47.7M
                ref *tobj;
708
47.7M
                bufptr[rlen] = '\0';
709
                /* Only pass a name object if the operator doesn't exist in systemdict
710
                 * i.e. it's an internal operator we have hidden
711
                 */
712
47.7M
                code = dict_find_string(systemdict, (const char *)bufptr, &tobj);
713
47.7M
                if (code <= 0) {
714
1.03M
                    buf[0] = buf[1] = buf[rlen + 2] = buf[rlen + 3] = '-';
715
1.03M
                    rlen += 4;
716
1.03M
                    bufptr = buf;
717
1.03M
                }
718
46.7M
                else {
719
46.7M
                    bufptr = NULL;
720
46.7M
                }
721
47.7M
            }
722
47.7M
            if (bufptr) {
723
1.03M
                code = name_ref(imemory, buf, rlen, osp, 1);
724
1.03M
                if (code < 0)
725
1.03M
                    make_null(osp);
726
1.03M
            }
727
47.7M
        }
728
48.2M
    }
729
48.2M
    goto again;
730
48.2M
}
731
static int
732
interp_exit(i_ctx_t *i_ctx_p)
733
232k
{
734
232k
    return gs_error_InterpreterExit;
735
232k
}
736
737
/* Only used (currently) with language switching:
738
 * allows the PS interpreter to co-exist with the
739
 * PJL interpreter.
740
 */
741
static int
742
zforceinterp_exit(i_ctx_t *i_ctx_p)
743
0
{
744
0
    os_ptr op = osp;
745
0
    stream *s;
746
747
0
    check_file(s, op);
748
0
    i_ctx_p->uel_position = stell(s)-1;
749
    /* resetfile */
750
0
    if (file_is_valid(s, op))
751
0
        sreset(s);
752
753
0
    if (!gs_lib_ctx_get_act_on_uel((gs_memory_t *)(i_ctx_p->memory.current)))
754
0
        return 0;
755
756
0
    gs_interp_reset(i_ctx_p);
757
    /* gs_interp_reset() actually leaves the op stack one entry below
758
     * the bottom of the stack, and that can cause problems depending
759
     * on the interpreter state at the end of the job.
760
     * So push a null object, and the return code before continuing.
761
     */
762
0
    push(2);
763
0
    op = osp;
764
0
    make_null(op - 1);
765
0
    make_int(op, gs_error_InterpreterExit);
766
0
    return_error(gs_error_Quit);
767
0
}
768
769
/* Set the GC signal for all VMs. */
770
static void
771
set_gc_signal(i_ctx_t *i_ctx_p, int value)
772
106M
{
773
106M
    gs_memory_gc_status_t stat;
774
106M
    int i;
775
776
530M
    for (i = 0; i < countof(idmemory->spaces_indexed); i++) {
777
424M
        gs_ref_memory_t *mem = idmemory->spaces_indexed[i];
778
424M
        gs_ref_memory_t *mem_stable;
779
780
424M
        if (mem == 0)
781
106M
            continue;
782
530M
        for (;; mem = mem_stable) {
783
530M
            mem_stable = (gs_ref_memory_t *)
784
530M
                gs_memory_stable((gs_memory_t *)mem);
785
530M
            gs_memory_gc_status(mem, &stat);
786
530M
            stat.signal_value = value;
787
530M
            gs_memory_set_gc_status(mem, &stat);
788
530M
            if (mem_stable == mem)
789
318M
                break;
790
530M
        }
791
318M
    }
792
106M
}
793
794
/* Create a printable string ref (or null) from an arbitrary ref.
795
 * For the purpose this is used here, it cannot fail, any
796
 * error in the process results in a null object, instead
797
 * of the string.
798
 */
799
static void obj_cvs_ref(i_ctx_t *i_ctx_p, const ref *in, ref *out)
800
0
{
801
0
    uint rlen;
802
0
    int code;
803
0
    byte sbuf[65], *buf = sbuf;
804
0
    uint len = sizeof(sbuf) - 1;
805
806
0
    code = obj_cvs(imemory, in, buf, len, &rlen, NULL);
807
0
    if (code == gs_error_rangecheck) {
808
0
        len = rlen;
809
0
        buf = gs_alloc_bytes(imemory, len + 1, "obj_cvs_ref");
810
0
        if (!buf)
811
0
            code = -1;
812
0
        else
813
0
            code = obj_cvs(imemory, in, buf, len, &rlen, NULL);
814
0
    }
815
0
    if (code < 0) {
816
0
        make_null(out);
817
0
    }
818
0
    else {
819
0
        buf[rlen] = '\0';
820
0
        code = string_to_ref((const char *)buf, out, iimemory, "obj_cvs_ref");
821
0
        if (code < 0)
822
0
            make_null(out);
823
0
    }
824
0
    if (buf != sbuf)
825
0
        gs_free_object(imemory, buf, "obj_cvs_ref");
826
0
    return;
827
0
}
828
829
/* Copy top elements of an overflowed stack into a (local) array. */
830
/* Adobe copies only 500 top elements, we copy up to 65535 top elements */
831
/* for better debugging, PLRM compliance, and backward compatibility. */
832
static int
833
copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr)
834
26
{
835
26
    uint size = ref_stack_count(pstack) - skip;
836
26
    uint save_space = ialloc_space(idmemory);
837
26
    int code, i;
838
26
    ref *safety, *safe;
839
840
26
    if (size > 65535)
841
18
        size = 65535;
842
26
    ialloc_set_space(idmemory, avm_local);
843
26
    code = ialloc_ref_array(arr, a_all, size, "copy_stack");
844
26
    if (code >= 0)
845
26
        code = ref_stack_store(pstack, arr, size, 0, 1, true, idmemory,
846
26
                               "copy_stack");
847
    /* If we are copying the exec stack, try to replace any oparrays with
848
     * the operator that references them
849
     * We also replace any internal objects (t_struct and t_astruct) with
850
     * string representations, since these can contain references to objects
851
     * with uncertain lifespans, it is safer not to risk them persisting.
852
     * Since we basically did this later on for the error handler, it isn't
853
     * a significant speed hit.
854
     */
855
26
    if (pstack == &e_stack) {
856
39.9k
        for (i = 0; i < size; i++) {
857
39.9k
            if (errorexec_find(i_ctx_p, &arr->value.refs[i]) < 0)
858
39.9k
                make_null(&arr->value.refs[i]);
859
39.9k
            else if (r_has_type(&arr->value.refs[i], t_struct)
860
39.9k
                  || r_has_type(&arr->value.refs[i], t_astruct)) {
861
0
                ref r;
862
0
                obj_cvs_ref(i_ctx_p, (const ref *)&arr->value.refs[i], &r);
863
0
                ref_assign(&arr->value.refs[i], &r);
864
0
            }
865
39.9k
        }
866
8
    }
867
26
    if (pstack == &o_stack && dict_find_string(systemdict, "SAFETY", &safety) > 0 &&
868
26
        dict_find_string(safety, "safe", &safe) > 0 && r_has_type(safe, t_boolean) &&
869
26
        safe->value.boolval == true) {
870
0
        code = ref_stack_array_sanitize(i_ctx_p, arr, arr);
871
0
        if (code < 0)
872
0
            return code;
873
0
    }
874
26
    ialloc_set_space(idmemory, save_space);
875
26
    return code;
876
26
}
877
878
/* Get the name corresponding to an error number. */
879
int
880
gs_errorname(i_ctx_t *i_ctx_p, int code, ref * perror_name)
881
48.2M
{
882
48.2M
    ref *perrordict, *pErrorNames;
883
884
48.2M
    if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 ||
885
48.2M
        dict_find_string(systemdict, "ErrorNames", &pErrorNames) <= 0
886
48.2M
        )
887
0
        return_error(gs_error_undefined);      /* errordict or ErrorNames not found?! */
888
48.2M
    return array_get(imemory, pErrorNames, (long)(-code - 1), perror_name);
889
48.2M
}
890
891
/* Store an error string in $error.errorinfo. */
892
/* This routine is here because of the proximity to the error handler. */
893
int
894
gs_errorinfo_put_string(i_ctx_t *i_ctx_p, const char *str)
895
0
{
896
0
    ref rstr;
897
0
    ref *pderror;
898
0
    int code = string_to_ref(str, &rstr, iimemory, "gs_errorinfo_put_string");
899
900
0
    if (code < 0)
901
0
        return code;
902
0
    if (dict_find_string(systemdict, "$error", &pderror) <= 0 ||
903
0
        !r_has_type(pderror, t_dictionary) ||
904
0
        idict_put_string(pderror, "errorinfo", &rstr) < 0
905
0
        )
906
0
        return_error(gs_error_Fatal);
907
0
    return 0;
908
0
}
909
910
/* Main interpreter. */
911
/* If execution terminates normally, return gs_error_InterpreterExit. */
912
/* If an error occurs, leave the current object in *perror_object */
913
/* and return a (negative) error code. */
914
static int
915
interp(/* lgtm [cpp/use-of-goto] */
916
       i_ctx_t **pi_ctx_p /* context for execution, updated if resched */,
917
       const ref * pref /* object to interpret */,
918
       ref * perror_object)
919
52.3M
{
920
52.3M
    i_ctx_t *i_ctx_p = *pi_ctx_p;
921
    /*
922
     * Note that iref may actually be either a ref * or a ref_packed *.
923
     * Certain DEC compilers assume that a ref * is ref-aligned even if it
924
     * is cast to a short *, and generate code on this assumption, leading
925
     * to "unaligned access" errors.  For this reason, we declare
926
     * iref_packed, and use a macro to cast it to the more aligned type
927
     * where necessary (which is almost everywhere it is used).  This may
928
     * lead to compiler warnings about "cast increases alignment
929
     * requirements", but this is less harmful than expensive traps at run
930
     * time.
931
     */
932
52.3M
    register const ref_packed *iref_packed = (const ref_packed *)pref;
933
    /*
934
     * To make matters worse, some versions of gcc/egcs have a bug that
935
     * leads them to assume that if iref_packed is EVER cast to a ref *,
936
     * it is ALWAYS ref-aligned.  We detect this in stdpre.h and provide
937
     * the following workaround:
938
     */
939
#ifdef ALIGNMENT_ALIASING_BUG
940
    const ref *iref_temp;
941
#  define IREF (iref_temp = (const ref *)iref_packed, iref_temp)
942
#else
943
6.79G
#  define IREF ((const ref *)iref_packed)
944
52.3M
#endif
945
24.6G
#define SET_IREF(rp) (iref_packed = (const ref_packed *)(rp))
946
52.3M
    register int icount = 0;    /* # of consecutive tokens at iref */
947
52.3M
    register os_ptr iosp = osp; /* private copy of osp */
948
52.3M
    register es_ptr iesp = esp; /* private copy of esp */
949
52.3M
    int code;
950
52.3M
    ref token;                  /* token read from file or string, */
951
                                /* must be declared in this scope */
952
52.3M
    ref *pvalue;
953
52.3M
    ref refnull;
954
52.3M
    uint opindex;               /* needed for oparrays */
955
52.3M
    os_ptr whichp;
956
957
    /*
958
     * We have to make the error information into a struct;
959
     * otherwise, the Watcom compiler will assign it to registers
960
     * strictly on the basis of textual frequency.
961
     * We also have to use ref_assign_inline everywhere, and
962
     * avoid direct assignments of refs, so that esi and edi
963
     * will remain available on Intel processors.
964
     */
965
52.3M
    struct interp_error_s {
966
52.3M
        int code;
967
52.3M
        int line;
968
52.3M
        const ref *obj;
969
52.3M
        ref full;
970
52.3M
    } ierror;
971
972
    /*
973
     * Get a pointer to the name table so that we can use the
974
     * inline version of name_index_ref.
975
     */
976
52.3M
    const name_table *const int_nt = imemory->gs_lib_ctx->gs_name_table;
977
978
52.3M
#define set_error(ecode)\
979
52.3M
  { ierror.code = ecode; ierror.line = __LINE__; }
980
52.3M
#define return_with_error(ecode, objp)\
981
52.3M
  { set_error(ecode); ierror.obj = objp; goto rwe; }
982
52.3M
#define return_with_error_iref(ecode)\
983
52.3M
  { set_error(ecode); goto rwei; }
984
52.3M
#define return_with_code_iref()\
985
52.3M
  { ierror.line = __LINE__; goto rweci; }
986
52.3M
#define return_with_stackoverflow(objp)\
987
52.3M
  { o_stack.requested = 1; return_with_error(gs_error_stackoverflow, objp); }
988
52.3M
#define return_with_stackoverflow_iref()\
989
52.3M
  { o_stack.requested = 1; return_with_error_iref(gs_error_stackoverflow); }
990
/*
991
 * If control reaches the special operators (x_add, etc.) as a result of
992
 * interpreting an executable name, iref points to the name, not the
993
 * operator, so the name rather than the operator becomes the error object,
994
 * which is wrong.  We detect and handle this case explicitly when an error
995
 * occurs, so as not to slow down the non-error case.
996
 */
997
52.3M
#define return_with_error_tx_op(err_code)\
998
52.3M
  { if (r_has_type(IREF, t_name)) {\
999
358
        return_with_error(err_code, pvalue);\
1000
3.55k
    } else {\
1001
3.55k
        return_with_error_iref(err_code);\
1002
0
    }\
1003
3.91k
  }
1004
1005
52.3M
    int *ticks_left = &imemory_system->gs_lib_ctx->gcsignal;
1006
1007
#if defined(DEBUG_TRACE_PS_OPERATORS) || defined(DEBUG)
1008
    int (*call_operator_fn)(op_proc_t, i_ctx_t *) = do_call_operator;
1009
1010
    if (gs_debug_c('!'))
1011
        call_operator_fn = do_call_operator_verbose;
1012
#endif
1013
1014
52.3M
    *ticks_left = i_ctx_p->time_slice_ticks;
1015
1016
52.3M
     make_null(&ierror.full);
1017
52.3M
     ierror.obj = &ierror.full;
1018
52.3M
     make_null(&refnull);
1019
52.3M
     pvalue = &refnull;
1020
1021
    /*
1022
     * If we exceed the VMThreshold, set *ticks_left to -100
1023
     * to alert the interpreter that we need to garbage collect.
1024
     */
1025
52.3M
    set_gc_signal(i_ctx_p, -100);
1026
1027
52.3M
    esfile_clear_cache();
1028
    /*
1029
     * From here on, if icount > 0, iref and icount correspond
1030
     * to the top entry on the execution stack: icount is the count
1031
     * of sequential entries remaining AFTER the current one.
1032
     */
1033
52.3M
#define IREF_NEXT(ip)\
1034
14.1G
  ((const ref_packed *)((const ref *)(ip) + 1))
1035
52.3M
#define IREF_NEXT_EITHER(ip)\
1036
10.6G
  ( r_is_packed(ip) ? (ip) + 1 : IREF_NEXT(ip) )
1037
52.3M
#define store_state(ep)\
1038
4.99G
  ( icount > 0 ? (ep->value.const_refs = IREF + 1, r_set_size(ep, icount)) : 0 )
1039
52.3M
#define store_state_short(ep)\
1040
6.11G
  ( icount > 0 ? (ep->value.packed = iref_packed + 1, r_set_size(ep, icount)) : 0 )
1041
52.3M
#define store_state_either(ep)\
1042
2.39G
  ( icount > 0 ? (ep->value.packed = IREF_NEXT_EITHER(iref_packed), r_set_size(ep, icount)) : 0 )
1043
52.3M
#define next()\
1044
16.1G
  if ( --icount > 0 ) { iref_packed = IREF_NEXT(iref_packed); goto top; } else goto out
1045
52.3M
#define next_short()\
1046
16.1G
  if ( --icount <= 0 ) { if ( icount < 0 ) goto up; iesp--; }\
1047
16.1G
  ++iref_packed; goto top
1048
52.3M
#define next_either()\
1049
13.3G
  if ( --icount <= 0 ) { if ( icount < 0 ) goto up; iesp--; }\
1050
13.3G
  iref_packed = IREF_NEXT_EITHER(iref_packed); goto top
1051
1052
#if !PACKED_SPECIAL_OPS
1053
#  undef next_either
1054
#  define next_either() next()
1055
#  undef store_state_either
1056
#  define store_state_either(ep) store_state(ep)
1057
#endif
1058
1059
    /* We want to recognize executable arrays here, */
1060
    /* so we push the argument on the estack and enter */
1061
    /* the loop at the bottom. */
1062
52.3M
    if (iesp >= estop)
1063
52.3M
        return_with_error(gs_error_execstackoverflow, pref);
1064
52.3M
    ++iesp;
1065
52.3M
    ref_assign_inline(iesp, pref);
1066
52.3M
    goto bot;
1067
61.1G
  top:
1068
        /*
1069
         * This is the top of the interpreter loop.
1070
         * iref points to the ref being interpreted.
1071
         * Note that this might be an element of a packed array,
1072
         * not a real ref: we carefully arranged the first 16 bits of
1073
         * a ref and of a packed array element so they could be distinguished
1074
         * from each other.  (See ghost.h and packed.h for more detail.)
1075
         */
1076
61.1G
    INCR(top);
1077
#ifdef DEBUG
1078
    /* Do a little validation on the top o-stack entry. */
1079
    if (iosp >= osbot &&
1080
        (r_type(iosp) == t__invalid || r_type(iosp) >= tx_next_op)
1081
        ) {
1082
        mlprintf(imemory, "Invalid value on o-stack!\n");
1083
        return_with_error_iref(gs_error_Fatal);
1084
    }
1085
    if (gs_debug['I'] ||
1086
        (gs_debug['i'] &&
1087
         (r_is_packed(iref_packed) ?
1088
          r_packed_is_name(iref_packed) :
1089
          r_has_type(IREF, t_name)))
1090
        ) {
1091
        os_ptr save_osp = osp;  /* avoid side-effects */
1092
        es_ptr save_esp = esp;
1093
1094
        osp = iosp;
1095
        esp = iesp;
1096
        dmlprintf5(imemory, "d%u,e%u<%u>"PRI_INTPTR"(%d): ",
1097
                  ref_stack_count(&d_stack), ref_stack_count(&e_stack),
1098
                  ref_stack_count(&o_stack), (intptr_t)IREF, icount);
1099
        debug_print_ref(imemory, IREF);
1100
        if (iosp >= osbot) {
1101
            dmputs(imemory, " // ");
1102
            debug_print_ref(imemory, iosp);
1103
        }
1104
        dmputc(imemory, '\n');
1105
        osp = save_osp;
1106
        esp = save_esp;
1107
        dmflush(imemory);
1108
    }
1109
#endif
1110
/* Objects that have attributes (arrays, dictionaries, files, and strings) */
1111
/* use lit and exec; other objects use plain and plain_exec. */
1112
61.1G
#define lit(t) type_xe_value(t, a_execute)
1113
61.1G
#define exec(t) type_xe_value(t, a_execute + a_executable)
1114
61.1G
#define nox(t) type_xe_value(t, 0)
1115
61.1G
#define nox_exec(t) type_xe_value(t, a_executable)
1116
61.1G
#define plain(t) type_xe_value(t, 0)
1117
61.1G
#define plain_exec(t) type_xe_value(t, a_executable)
1118
    /*
1119
     * We have to populate enough cases of the switch statement to force
1120
     * some compilers to use a dispatch rather than a testing loop.
1121
     * What a nuisance!
1122
     */
1123
61.1G
    switch (r_type_xe(iref_packed)) {
1124
            /* Access errors. */
1125
0
#define cases_invalid()\
1126
0
  case plain(t__invalid): case plain_exec(t__invalid)
1127
0
          cases_invalid():
1128
0
            return_with_error_iref(gs_error_Fatal);
1129
0
#define cases_nox()\
1130
0
  case nox_exec(t_array): case nox_exec(t_dictionary):\
1131
0
  case nox_exec(t_file): case nox_exec(t_string):\
1132
0
  case nox_exec(t_mixedarray): case nox_exec(t_shortarray)
1133
0
          cases_nox():
1134
0
            return_with_error_iref(gs_error_invalidaccess);
1135
            /*
1136
             * Literal objects.  We have to enumerate all the types.
1137
             * In fact, we have to include some extra plain_exec entries
1138
             * just to populate the switch.  We break them up into groups
1139
             * to avoid overflowing some preprocessors.
1140
             */
1141
0
#define cases_lit_1()\
1142
147M
  case lit(t_array): case nox(t_array):\
1143
715M
  case plain(t_boolean): case plain_exec(t_boolean):\
1144
1.08G
  case lit(t_dictionary): case nox(t_dictionary)
1145
0
#define cases_lit_2()\
1146
1.09G
  case lit(t_file): case nox(t_file):\
1147
1.09G
  case plain(t_fontID): case plain_exec(t_fontID):\
1148
1.73G
  case plain(t_integer): case plain_exec(t_integer):\
1149
1.73G
  case plain(t_mark): case plain_exec(t_mark)
1150
0
#define cases_lit_3()\
1151
2.76G
  case plain(t_name):\
1152
3.11G
  case plain(t_null):\
1153
3.11G
  case plain(t_oparray):\
1154
3.11G
  case plain(t_operator)
1155
0
#define cases_lit_4()\
1156
3.18G
  case plain(t_real): case plain_exec(t_real):\
1157
3.18G
  case plain(t_save): case plain_exec(t_save):\
1158
3.34G
  case lit(t_string): case nox(t_string)
1159
0
#define cases_lit_5()\
1160
4.42G
  case lit(t_mixedarray): case nox(t_mixedarray):\
1161
4.42G
  case lit(t_shortarray): case nox(t_shortarray):\
1162
4.42G
  case plain(t_device): case plain_exec(t_device):\
1163
4.42G
  case plain(t_struct): case plain_exec(t_struct):\
1164
4.42G
  case plain(t_astruct): case plain_exec(t_astruct):\
1165
4.42G
  case plain(t_pdfctx): case plain_exec(t_pdfctx)
1166
            /* Executable arrays are treated as literals in direct execution. */
1167
0
#define cases_lit_array()\
1168
6.88G
  case exec(t_array): case exec(t_mixedarray): case exec(t_shortarray)
1169
3.43G
          cases_lit_1():
1170
9.58G
          cases_lit_2():
1171
11.1G
          cases_lit_3():
1172
17.9G
          cases_lit_4():
1173
17.9G
          cases_lit_5():
1174
4.18G
            INCR(lit);
1175
4.18G
            break;
1176
6.88G
          cases_lit_array():
1177
6.88G
            INCR(lit_array);
1178
6.88G
            break;
1179
            /* Special operators. */
1180
70.9M
        case plain_exec(tx_op_add):
1181
321M
x_add:      INCR(x_add);
1182
321M
            osp = iosp; /* sync o_stack */
1183
321M
            if ((code = zop_add(i_ctx_p)) < 0)
1184
321M
                return_with_error_tx_op(code);
1185
321M
            iosp--;
1186
321M
            next_either();
1187
18.0M
        case plain_exec(tx_op_def):
1188
285M
x_def:      INCR(x_def);
1189
285M
            osp = iosp; /* sync o_stack */
1190
285M
            if ((code = zop_def(i_ctx_p)) < 0)
1191
285M
                return_with_error_tx_op(code);
1192
285M
            iosp -= 2;
1193
285M
            next_either();
1194
296M
        case plain_exec(tx_op_dup):
1195
3.74G
x_dup:      INCR(x_dup);
1196
3.74G
            if (iosp < osbot)
1197
3.74G
                return_with_error_tx_op(gs_error_stackunderflow);
1198
3.74G
            if (iosp >= ostop) {
1199
247
                o_stack.requested = 1;
1200
247
                return_with_error_tx_op(gs_error_stackoverflow);
1201
0
            }
1202
3.74G
            iosp++;
1203
3.74G
            ref_assign_inline(iosp, iosp - 1);
1204
3.74G
            next_either();
1205
491M
        case plain_exec(tx_op_exch):
1206
2.13G
x_exch:     INCR(x_exch);
1207
2.13G
            if (iosp <= osbot)
1208
2.13G
                return_with_error_tx_op(gs_error_stackunderflow);
1209
2.13G
            ref_assign_inline(&token, iosp);
1210
2.13G
            ref_assign_inline(iosp, iosp - 1);
1211
2.13G
            ref_assign_inline(iosp - 1, &token);
1212
2.13G
            next_either();
1213
441M
        case plain_exec(tx_op_if):
1214
1.66G
x_if:       INCR(x_if);
1215
1.66G
            if (!r_is_proc(iosp))
1216
1.66G
                return_with_error_tx_op(check_proc_failed(iosp));
1217
1.66G
            if (!r_has_type(iosp - 1, t_boolean))
1218
20
                return_with_error_tx_op((iosp <= osbot ?
1219
1.66G
                                        gs_error_stackunderflow : gs_error_typecheck));
1220
1.66G
            if (!iosp[-1].value.boolval) {
1221
1.37G
                iosp -= 2;
1222
1.37G
                next_either();
1223
1.37G
            }
1224
293M
            if (iesp >= estop)
1225
293M
                return_with_error_tx_op(gs_error_execstackoverflow);
1226
293M
            store_state_either(iesp);
1227
293M
            whichp = iosp;
1228
293M
            iosp -= 2;
1229
293M
            goto ifup;
1230
442M
        case plain_exec(tx_op_ifelse):
1231
2.10G
x_ifelse:   INCR(x_ifelse);
1232
2.10G
            if (!r_is_proc(iosp))
1233
2.10G
                return_with_error_tx_op(check_proc_failed(iosp));
1234
2.10G
            if (!r_is_proc(iosp - 1))
1235
2.10G
                return_with_error_tx_op(check_proc_failed(iosp - 1));
1236
2.10G
            if (!r_has_type(iosp - 2, t_boolean))
1237
51
                return_with_error_tx_op((iosp < osbot + 2 ?
1238
2.10G
                                        gs_error_stackunderflow : gs_error_typecheck));
1239
2.10G
            if (iesp >= estop)
1240
2.10G
                return_with_error_tx_op(gs_error_execstackoverflow);
1241
2.10G
            store_state_either(iesp);
1242
2.10G
            whichp = (iosp[-2].value.boolval ? iosp - 1 : iosp);
1243
2.10G
            iosp -= 3;
1244
            /* Open code "up" for the array case(s) */
1245
2.39G
          ifup:if ((icount = r_size(whichp) - 1) <= 0) {
1246
660M
                if (icount < 0)
1247
0
                    goto up;    /* 0-element proc */
1248
660M
                SET_IREF(whichp->value.refs);   /* 1-element proc */
1249
660M
                if (--(*ticks_left) > 0)
1250
660M
                    goto top;
1251
660M
            }
1252
1.73G
            ++iesp;
1253
            /* Do a ref_assign, but also set iref. */
1254
1.73G
            iesp->tas = whichp->tas;
1255
1.73G
            SET_IREF(iesp->value.refs = whichp->value.refs);
1256
1.73G
            if (--(*ticks_left) > 0)
1257
1.73G
                goto top;
1258
244k
            goto slice;
1259
63.6M
        case plain_exec(tx_op_index):
1260
1.57G
x_index:    INCR(x_index);
1261
1.57G
            osp = iosp; /* zindex references o_stack */
1262
1.57G
            if ((code = zindex(i_ctx_p)) < 0)
1263
1.57G
                return_with_error_tx_op(code);
1264
1.57G
            next_either();
1265
723M
        case plain_exec(tx_op_pop):
1266
2.80G
x_pop:      INCR(x_pop);
1267
2.80G
            if (iosp < osbot)
1268
2.80G
                return_with_error_tx_op(gs_error_stackunderflow);
1269
2.80G
            iosp--;
1270
2.80G
            next_either();
1271
238M
        case plain_exec(tx_op_roll):
1272
1.06G
x_roll:     INCR(x_roll);
1273
1.06G
            osp = iosp; /* zroll references o_stack */
1274
1.06G
            if ((code = zroll(i_ctx_p)) < 0)
1275
1.06G
                return_with_error_tx_op(code);
1276
1.06G
            iosp -= 2;
1277
1.06G
            next_either();
1278
28.3M
        case plain_exec(tx_op_sub):
1279
55.1M
x_sub:      INCR(x_sub);
1280
55.1M
            osp = iosp; /* sync o_stack */
1281
55.1M
            if ((code = zop_sub(i_ctx_p)) < 0)
1282
55.1M
                return_with_error_tx_op(code);
1283
55.1M
            iosp--;
1284
55.1M
            next_either();
1285
            /* Executable types. */
1286
1.87M
        case plain_exec(t_null):
1287
1.87M
            goto bot;
1288
375M
        case plain_exec(t_oparray):
1289
            /* Replace with the definition and go again. */
1290
375M
            INCR(exec_array);
1291
375M
            opindex = op_index(IREF);
1292
375M
            pvalue = (ref *)IREF->value.const_refs;
1293
747M
          opst:         /* Prepare to call a t_oparray procedure in *pvalue. */
1294
747M
            store_state(iesp);
1295
1.86G
          oppr:         /* Record the stack depths in case of failure. */
1296
1.86G
            if (iesp >= estop - 4)
1297
1.86G
                return_with_error_iref(gs_error_execstackoverflow);
1298
1.86G
            iesp += 5;
1299
1.86G
            osp = iosp;         /* ref_stack_count_inline needs this */
1300
1.86G
            make_mark_estack(iesp - 4, es_other, oparray_cleanup);
1301
1.86G
            make_int(iesp - 3, opindex); /* for .errorexec effect */
1302
1.86G
            make_int(iesp - 2, ref_stack_count_inline(&o_stack));
1303
1.86G
            make_int(iesp - 1, ref_stack_count_inline(&d_stack));
1304
1.86G
            make_op_estack(iesp, oparray_pop);
1305
1.86G
            goto pr;
1306
238M
          prst:         /* Prepare to call the procedure (array) in *pvalue. */
1307
238M
            store_state(iesp);
1308
2.34G
          pr:                   /* Call the array in *pvalue.  State has been stored. */
1309
            /* We want to do this check before assigning icount so icount is correct
1310
             * in the event of a gs_error_execstackoverflow
1311
             */
1312
2.34G
            if (iesp >= estop) {
1313
1
                return_with_error_iref(gs_error_execstackoverflow);
1314
0
            }
1315
2.34G
            if ((icount = r_size(pvalue) - 1) <= 0) {
1316
34.8M
                if (icount < 0)
1317
434k
                    goto up;    /* 0-element proc */
1318
34.3M
                SET_IREF(pvalue->value.refs);   /* 1-element proc */
1319
34.3M
                if (--(*ticks_left) > 0)
1320
34.3M
                    goto top;
1321
34.3M
            }
1322
2.30G
            ++iesp;
1323
            /* Do a ref_assign, but also set iref. */
1324
2.30G
            iesp->tas = pvalue->tas;
1325
2.30G
            SET_IREF(iesp->value.refs = pvalue->value.refs);
1326
2.30G
            if (--(*ticks_left) > 0)
1327
2.30G
                goto top;
1328
43.5k
            goto slice;
1329
8.48G
        case plain_exec(t_operator):
1330
8.48G
            INCR(exec_operator);
1331
8.48G
            if (--(*ticks_left) <= 0) {    /* The following doesn't work, */
1332
                /* and I can't figure out why. */
1333
/****** goto sst; ******/
1334
148k
            }
1335
8.48G
            esp = iesp;         /* save for operator */
1336
8.48G
            osp = iosp;         /* ditto */
1337
            /* Operator routines take osp as an argument. */
1338
            /* This is just a convenience, since they adjust */
1339
            /* osp themselves to reflect the results. */
1340
            /* Operators that (net) push information on the */
1341
            /* operand stack must check for overflow: */
1342
            /* this normally happens automatically through */
1343
            /* the push macro (in oper.h). */
1344
            /* Operators that do not typecheck their operands, */
1345
            /* or take a variable number of arguments, */
1346
            /* must check explicitly for stack underflow. */
1347
            /* (See oper.h for more detail.) */
1348
            /* Note that each case must set iosp = osp: */
1349
            /* this is so we can switch on code without having to */
1350
            /* store it and reload it (for dumb compilers). */
1351
8.48G
            switch (code = call_operator(real_opproc(IREF), i_ctx_p)) {
1352
3.86G
                case 0: /* normal case */
1353
3.88G
                case 1: /* alternative success case */
1354
3.88G
                    iosp = osp;
1355
3.88G
                    next();
1356
2.55G
                case o_push_estack:     /* store the state and go to up */
1357
2.55G
                    store_state(iesp);
1358
3.42G
                  opush:iosp = osp;
1359
3.42G
                    iesp = esp;
1360
3.42G
                    if (--(*ticks_left) > 0)
1361
3.42G
                        goto up;
1362
43.7k
                    goto slice;
1363
2.04G
                case o_pop_estack:      /* just go to up */
1364
2.04G
                  opop:iosp = osp;
1365
2.04G
                    if (esp == iesp)
1366
1.48M
                        goto bot;
1367
2.04G
                    iesp = esp;
1368
2.04G
                    goto up;
1369
0
                case gs_error_Remap_Color:
1370
0
oe_remap:           store_state(iesp);
1371
0
remap:              if (iesp + 2 >= estop) {
1372
0
                        esp = iesp;
1373
0
                        code = ref_stack_extend(&e_stack, 2);
1374
0
                        if (code < 0)
1375
0
                            return_with_error_iref(code);
1376
0
                        iesp = esp;
1377
0
                    }
1378
0
                    packed_get(imemory, iref_packed, iesp + 1);
1379
0
                    make_oper(iesp + 2, 0,
1380
0
                              r_ptr(&istate->remap_color_info,
1381
0
                                    int_remap_color_info_t)->proc);
1382
0
                    iesp += 2;
1383
0
                    goto up;
1384
8.48G
            }
1385
2.66M
            iosp = osp;
1386
2.66M
            iesp = esp;
1387
2.66M
            return_with_code_iref();
1388
1.98G
        case plain_exec(t_name):
1389
1.98G
            INCR(exec_name);
1390
1.98G
            pvalue = IREF->value.pname->pvalue;
1391
1.98G
            if (!pv_valid(pvalue)) {
1392
1.85G
                uint nidx = names_index(int_nt, IREF);
1393
1.85G
                uint htemp = 0;
1394
1395
1.85G
                INCR(find_name);
1396
1.85G
                if ((pvalue = dict_find_name_by_index_inline(nidx, htemp)) == 0)
1397
1.85G
                    return_with_error_iref(gs_error_undefined);
1398
1.85G
            }
1399
            /* Dispatch on the type of the value. */
1400
            /* Again, we have to over-populate the switch. */
1401
1.98G
            switch (r_type_xe(pvalue)) {
1402
0
                  cases_invalid():
1403
0
                    return_with_error_iref(gs_error_Fatal);
1404
0
                  cases_nox():  /* access errors */
1405
0
                    return_with_error_iref(gs_error_invalidaccess);
1406
470M
                  cases_lit_1():
1407
1.72G
                  cases_lit_2():
1408
1.72G
                  cases_lit_3():
1409
1.43G
                  cases_lit_4():
1410
2.87G
                  cases_lit_5():
1411
2.87G
                      INCR(name_lit);
1412
                    /* Just push the value */
1413
2.87G
                    if (iosp >= ostop)
1414
239M
                        return_with_stackoverflow(pvalue);
1415
239M
                    ++iosp;
1416
239M
                    ref_assign_inline(iosp, pvalue);
1417
239M
                    next();
1418
16.7M
                case exec(t_array):
1419
205M
                case exec(t_mixedarray):
1420
238M
                case exec(t_shortarray):
1421
238M
                    INCR(name_proc);
1422
                    /* This is an executable procedure, execute it. */
1423
238M
                    goto prst;
1424
3.09M
                case plain_exec(tx_op_add):
1425
3.09M
                    goto x_add;
1426
163M
                case plain_exec(tx_op_def):
1427
163M
                    goto x_def;
1428
15.9M
                case plain_exec(tx_op_dup):
1429
15.9M
                    goto x_dup;
1430
21.1M
                case plain_exec(tx_op_exch):
1431
21.1M
                    goto x_exch;
1432
18.7M
                case plain_exec(tx_op_if):
1433
18.7M
                    goto x_if;
1434
5.42M
                case plain_exec(tx_op_ifelse):
1435
5.42M
                    goto x_ifelse;
1436
7.06M
                case plain_exec(tx_op_index):
1437
7.06M
                    goto x_index;
1438
19.3M
                case plain_exec(tx_op_pop):
1439
19.3M
                    goto x_pop;
1440
3.57M
                case plain_exec(tx_op_roll):
1441
3.57M
                    goto x_roll;
1442
646k
                case plain_exec(tx_op_sub):
1443
646k
                    goto x_sub;
1444
0
                case plain_exec(t_null):
1445
0
                    goto bot;
1446
372M
                case plain_exec(t_oparray):
1447
372M
                    INCR(name_oparray);
1448
372M
                    opindex = op_index(pvalue);
1449
372M
                    pvalue = (ref *)pvalue->value.const_refs;
1450
372M
                    goto opst;
1451
872M
                case plain_exec(t_operator):
1452
872M
                    INCR(name_operator);
1453
872M
                    {           /* Shortcut for operators. */
1454
                        /* See above for the logic. */
1455
872M
                        if (--(*ticks_left) <= 0) {        /* The following doesn't work, */
1456
                            /* and I can't figure out why. */
1457
/****** goto sst; ******/
1458
1.01k
                        }
1459
872M
                        esp = iesp;
1460
872M
                        osp = iosp;
1461
872M
                        switch (code = call_operator(real_opproc(pvalue),
1462
872M
                                                     i_ctx_p)
1463
872M
                                ) {
1464
848M
                            case 0:     /* normal case */
1465
860M
                            case 1:     /* alternative success case */
1466
860M
                                iosp = osp;
1467
860M
                                next();
1468
10.4M
                            case o_push_estack:
1469
10.4M
                                store_state(iesp);
1470
10.4M
                                goto opush;
1471
810k
                            case o_pop_estack:
1472
810k
                                goto opop;
1473
0
                            case gs_error_Remap_Color:
1474
0
                                goto oe_remap;
1475
872M
                        }
1476
93.1k
                        iosp = osp;
1477
93.1k
                        iesp = esp;
1478
93.1k
                        return_with_error(code, pvalue);
1479
0
                    }
1480
0
                case plain_exec(t_name):
1481
0
                case exec(t_file):
1482
0
                case exec(t_string):
1483
334k
                default:
1484
                    /* Not a procedure, reinterpret it. */
1485
334k
                    store_state(iesp);
1486
334k
                    icount = 0;
1487
334k
                    SET_IREF(pvalue);
1488
334k
                    goto top;
1489
1.98G
            }
1490
1.43G
        case exec(t_file):
1491
1.43G
            {   /* Executable file.  Read the next token and interpret it. */
1492
1.43G
                stream *s;
1493
1.43G
                scanner_state sstate;
1494
1495
1.43G
                check_read_known_file(i_ctx_p, s, IREF, return_with_error_iref);
1496
3.74G
            rt:
1497
3.74G
                if (iosp >= ostop)      /* check early */
1498
3.74G
                    return_with_stackoverflow_iref();
1499
3.74G
                osp = iosp;     /* gs_scan_token uses ostack */
1500
3.74G
                gs_scanner_init_options(&sstate, IREF, i_ctx_p->scanner_options);
1501
3.74G
            again:
1502
3.74G
                code = gs_scan_token(i_ctx_p, &token, &sstate);
1503
3.74G
                iosp = osp;     /* ditto */
1504
3.74G
                switch (code) {
1505
3.74G
                    case 0:     /* read a token */
1506
                        /* It's worth checking for literals, which make up */
1507
                        /* the majority of input tokens, before storing the */
1508
                        /* state on the e-stack.  Note that because of //, */
1509
                        /* the token may have *any* type and attributes. */
1510
                        /* Note also that executable arrays aren't executed */
1511
                        /* at the top level -- they're treated as literals. */
1512
3.74G
                        if (!r_has_attr(&token, a_executable) ||
1513
3.74G
                            r_is_array(&token)
1514
3.74G
                            ) { /* If gs_scan_token used the o-stack, */
1515
                            /* we know we can do a push now; if not, */
1516
                            /* the pre-check is still valid. */
1517
2.30G
                            iosp++;
1518
2.30G
                            ref_assign_inline(iosp, &token);
1519
2.30G
                            goto rt;
1520
2.30G
                        }
1521
1.43G
                        store_state(iesp);
1522
                        /* Push the file on the e-stack */
1523
1.43G
                        if (iesp >= estop)
1524
1.43G
                            return_with_error_iref(gs_error_execstackoverflow);
1525
1.43G
                        esfile_set_cache(++iesp);
1526
1.43G
                        ref_assign_inline(iesp, IREF);
1527
1.43G
                        SET_IREF(&token);
1528
1.43G
                        icount = 0;
1529
1.43G
                        goto top;
1530
269
                    case gs_error_undefined:   /* //name undefined */
1531
269
                        gs_scanner_error_object(i_ctx_p, &sstate, &token);
1532
269
                        return_with_error(code, &token);
1533
725k
                    case scan_EOF:      /* end of file */
1534
725k
                        esfile_clear_cache();
1535
725k
                        goto bot;
1536
7.65k
                    case scan_BOS:
1537
                        /* Binary object sequences */
1538
                        /* ARE executed at the top level. */
1539
7.65k
                        store_state(iesp);
1540
                        /* Push the file on the e-stack */
1541
7.65k
                        if (iesp >= estop)
1542
7.65k
                            return_with_error_iref(gs_error_execstackoverflow);
1543
7.65k
                        esfile_set_cache(++iesp);
1544
7.65k
                        ref_assign_inline(iesp, IREF);
1545
7.65k
                        pvalue = &token;
1546
7.65k
                        goto pr;
1547
964k
                    case scan_Refill:
1548
964k
                        store_state(iesp);
1549
                        /* iref may point into the exec stack; */
1550
                        /* save its referent now. */
1551
964k
                        ref_assign_inline(&token, IREF);
1552
                        /* Push the file on the e-stack */
1553
964k
                        if (iesp >= estop)
1554
964k
                            return_with_error_iref(gs_error_execstackoverflow);
1555
964k
                        ++iesp;
1556
964k
                        ref_assign_inline(iesp, &token);
1557
964k
                        esp = iesp;
1558
964k
                        osp = iosp;
1559
964k
                        code = gs_scan_handle_refill(i_ctx_p, &sstate, true,
1560
964k
                                                     ztokenexec_continue);
1561
1.03M
                scan_cont:
1562
1.03M
                        iosp = osp;
1563
1.03M
                        iesp = esp;
1564
1.03M
                        switch (code) {
1565
249k
                            case 0:
1566
249k
                                iesp--;         /* don't push the file */
1567
249k
                                goto again;     /* stacks are unchanged */
1568
785k
                            case o_push_estack:
1569
785k
                                esfile_clear_cache();
1570
785k
                                if (--(*ticks_left) > 0)
1571
785k
                                    goto up;
1572
179
                                goto slice;
1573
1.03M
                        }
1574
                        /* must be an error */
1575
697
                        iesp--; /* don't push the file */
1576
697
                        return_with_code_iref();
1577
0
                    case scan_Comment:
1578
71.6k
                    case scan_DSC_Comment: {
1579
                        /* See scan_Refill above for comments. */
1580
71.6k
                        ref file_token;
1581
1582
71.6k
                        store_state(iesp);
1583
71.6k
                        ref_assign_inline(&file_token, IREF);
1584
71.6k
                        if (iesp >= estop)
1585
71.6k
                            return_with_error_iref(gs_error_execstackoverflow);
1586
71.6k
                        ++iesp;
1587
71.6k
                        ref_assign_inline(iesp, &file_token);
1588
71.6k
                        esp = iesp;
1589
71.6k
                        osp = iosp;
1590
71.6k
                        code = ztoken_handle_comment(i_ctx_p,
1591
71.6k
                                                     &sstate, &token,
1592
71.6k
                                                     code, true, true,
1593
71.6k
                                                     ztokenexec_continue);
1594
71.6k
                    }
1595
0
                        goto scan_cont;
1596
13.9k
                    default:    /* error */
1597
13.9k
                        ref_assign_inline(&token, IREF);
1598
13.9k
                        gs_scanner_error_object(i_ctx_p, &sstate, &token);
1599
13.9k
                        return_with_error(code, &token);
1600
3.74G
                }
1601
3.74G
            }
1602
446k
        case exec(t_string):
1603
446k
            {                   /* Executable string.  Read a token and interpret it. */
1604
446k
                stream ss;
1605
446k
                scanner_state sstate;
1606
1607
446k
                s_init(&ss, NULL);
1608
446k
                sread_string(&ss, IREF->value.bytes, r_size(IREF));
1609
446k
                gs_scanner_init_stream_options(&sstate, &ss, SCAN_FROM_STRING);
1610
446k
                osp = iosp;     /* gs_scan_token uses ostack */
1611
446k
                code = gs_scan_token(i_ctx_p, &token, &sstate);
1612
446k
                iosp = osp;     /* ditto */
1613
446k
                switch (code) {
1614
446k
                    case 0:     /* read a token */
1615
446k
                    case scan_BOS:      /* binary object sequence */
1616
446k
                        store_state(iesp);
1617
                        /* If the updated string isn't empty, push it back */
1618
                        /* on the e-stack. */
1619
446k
                        {
1620
                            /* This is just the available buffer size, so
1621
                               a signed int is plenty big
1622
                             */
1623
446k
                            int size = sbufavailable(&ss);
1624
1625
446k
                            if (size > 0) {
1626
8
                                if (iesp >= estop)
1627
8
                                    return_with_error_iref(gs_error_execstackoverflow);
1628
8
                                ++iesp;
1629
8
                                iesp->tas.type_attrs = IREF->tas.type_attrs;
1630
8
                                iesp->value.const_bytes = sbufptr(&ss);
1631
8
                                r_set_size(iesp, size);
1632
8
                            }
1633
446k
                        }
1634
446k
                        if (code == 0) {
1635
446k
                            SET_IREF(&token);
1636
446k
                            icount = 0;
1637
446k
                            goto top;
1638
446k
                        }
1639
                        /* Handle BOS specially */
1640
0
                        pvalue = &token;
1641
0
                        goto pr;
1642
0
                    case scan_EOF:      /* end of string */
1643
0
                        goto bot;
1644
0
                    case scan_Refill:   /* error */
1645
0
                        code = gs_note_error(gs_error_syntaxerror);
1646
                        /* fall through */
1647
0
                    default:    /* error */
1648
0
                        ref_assign_inline(&token, IREF);
1649
0
                        gs_scanner_error_object(i_ctx_p, &sstate, &token);
1650
0
                        return_with_error(code, &token);
1651
446k
                }
1652
446k
            }
1653
            /* Handle packed arrays here by re-dispatching. */
1654
            /* This also picks up some anomalous cases of non-packed arrays. */
1655
34.9G
        default:
1656
34.9G
            {
1657
34.9G
                uint index;
1658
1659
34.9G
                switch (*iref_packed >> r_packed_type_shift) {
1660
334k
                    case pt_full_ref:
1661
334k
                    case pt_full_ref + 1:
1662
334k
                        INCR(p_full);
1663
334k
                        if (iosp >= ostop)
1664
334k
                            return_with_stackoverflow_iref();
1665
                        /* We know this can't be an executable object */
1666
                        /* requiring special handling, so we just push it. */
1667
334k
                        ++iosp;
1668
                        /* We know that refs are properly aligned: */
1669
                        /* see packed.h for details. */
1670
334k
                        ref_assign_inline(iosp, IREF);
1671
334k
                        next();
1672
23.4G
                    case pt_executable_operator:
1673
23.4G
                        index = *iref_packed & packed_value_mask;
1674
23.4G
                        if (--(*ticks_left) <= 0) {        /* The following doesn't work, */
1675
                            /* and I can't figure out why. */
1676
/****** goto sst_short; ******/
1677
904k
                        }
1678
23.4G
                        if (!op_index_is_operator(index)) {
1679
1.11G
                            INCR(p_exec_oparray);
1680
1.11G
                            store_state_short(iesp);
1681
1.11G
                            opindex = index;
1682
                            /* Call the operator procedure. */
1683
1.11G
                            index -= op_def_count;
1684
1.11G
                            pvalue = (ref *)
1685
1.11G
                                (index < r_size(&i_ctx_p->op_array_table_global.table) ?
1686
1.11G
                                 i_ctx_p->op_array_table_global.table.value.const_refs +
1687
1.11G
                                 index :
1688
1.11G
                                 i_ctx_p->op_array_table_local.table.value.const_refs +
1689
0
                                 (index - r_size(&i_ctx_p->op_array_table_global.table)));
1690
1.11G
                            goto oppr;
1691
1.11G
                        }
1692
23.4G
                        INCR(p_exec_operator);
1693
                        /* See the main plain_exec(t_operator) case */
1694
                        /* for details of what happens here. */
1695
22.3G
#if PACKED_SPECIAL_OPS
1696
                        /*
1697
                         * We arranged in iinit.c that the special ops
1698
                         * have operator indices starting at 1.
1699
                         *
1700
                         * The (int) cast in the next line is required
1701
                         * because some compilers don't allow arithmetic
1702
                         * involving two different enumerated types.
1703
                         */
1704
22.3G
#  define case_xop(xop) case xop - (int)tx_op + 1
1705
22.3G
                        switch (index) {
1706
247M
                              case_xop(tx_op_add):goto x_add;
1707
104M
                              case_xop(tx_op_def):goto x_def;
1708
3.42G
                              case_xop(tx_op_dup):goto x_dup;
1709
1.62G
                              case_xop(tx_op_exch):goto x_exch;
1710
1.20G
                              case_xop(tx_op_if):goto x_if;
1711
1.65G
                              case_xop(tx_op_ifelse):goto x_ifelse;
1712
1.50G
                              case_xop(tx_op_index):goto x_index;
1713
2.06G
                              case_xop(tx_op_pop):goto x_pop;
1714
824M
                              case_xop(tx_op_roll):goto x_roll;
1715
26.1M
                              case_xop(tx_op_sub):goto x_sub;
1716
0
                            case 0:     /* for dumb compilers */
1717
9.69G
                            default:
1718
9.69G
                                ;
1719
22.3G
                        }
1720
9.69G
#  undef case_xop
1721
9.69G
#endif
1722
22.3G
                        INCR(p_exec_non_x_operator);
1723
9.69G
                        esp = iesp;
1724
9.69G
                        osp = iosp;
1725
9.69G
                        switch (code = call_operator(op_index_proc(index), i_ctx_p)) {
1726
8.72G
                            case 0:
1727
8.72G
                            case 1:
1728
8.72G
                                iosp = osp;
1729
8.72G
                                next_short();
1730
859M
                            case o_push_estack:
1731
859M
                                store_state_short(iesp);
1732
859M
                                goto opush;
1733
62.2M
                            case o_pop_estack:
1734
62.2M
                                iosp = osp;
1735
62.2M
                                if (esp == iesp) {
1736
1.67M
                                    next_short();
1737
1.67M
                                }
1738
60.5M
                                iesp = esp;
1739
60.5M
                                goto up;
1740
0
                            case gs_error_Remap_Color:
1741
0
                                store_state_short(iesp);
1742
0
                                goto remap;
1743
9.69G
                        }
1744
46.9M
                        iosp = osp;
1745
46.9M
                        iesp = esp;
1746
46.9M
                        return_with_code_iref();
1747
5.81G
                    case pt_integer:
1748
5.81G
                        INCR(p_integer);
1749
5.81G
                        if (iosp >= ostop)
1750
5.81G
                            return_with_stackoverflow_iref();
1751
5.81G
                        ++iosp;
1752
5.81G
                        make_int(iosp,
1753
5.81G
                                 ((int)*iref_packed & packed_int_mask) +
1754
5.81G
                                 packed_min_intval);
1755
5.81G
                        next_short();
1756
1.36G
                    case pt_literal_name:
1757
1.36G
                        INCR(p_lit_name);
1758
1.36G
                        {
1759
1.36G
                            uint nidx = *iref_packed & packed_value_mask;
1760
1761
1.36G
                            if (iosp >= ostop)
1762
1.36G
                                return_with_stackoverflow_iref();
1763
1.36G
                            ++iosp;
1764
1.36G
                            name_index_ref_inline(int_nt, nidx, iosp);
1765
1.36G
                            next_short();
1766
1.36G
                        }
1767
4.30G
                    case pt_executable_name:
1768
4.30G
                        INCR(p_exec_name);
1769
4.30G
                        {
1770
4.30G
                            uint nidx = *iref_packed & packed_value_mask;
1771
1772
4.30G
                            pvalue = name_index_ptr_inline(int_nt, nidx)->pvalue;
1773
4.30G
                            if (!pv_valid(pvalue)) {
1774
4.10G
                                uint htemp = 0;
1775
1776
4.10G
                                INCR(p_find_name);
1777
4.10G
                                if ((pvalue = dict_find_name_by_index_inline(nidx, htemp)) == 0) {
1778
0
                                    names_index_ref(int_nt, nidx, &token);
1779
0
                                    return_with_error(gs_error_undefined, &token);
1780
0
                                }
1781
4.10G
                            }
1782
4.30G
                            if (r_has_masked_attrs(pvalue, a_execute, a_execute + a_executable)) {      /* Literal, push it. */
1783
204M
                                INCR(p_name_lit);
1784
204M
                                if (iosp >= ostop)
1785
204M
                                    return_with_stackoverflow_iref();
1786
204M
                                ++iosp;
1787
204M
                                ref_assign_inline(iosp, pvalue);
1788
204M
                                next_short();
1789
204M
                            }
1790
4.09G
                            if (r_is_proc(pvalue)) {    /* This is an executable procedure, */
1791
                                /* execute it. */
1792
242M
                                INCR(p_name_proc);
1793
242M
                                store_state_short(iesp);
1794
242M
                                goto pr;
1795
242M
                            }
1796
                            /* Not a literal or procedure, reinterpret it. */
1797
3.85G
                            store_state_short(iesp);
1798
3.85G
                            icount = 0;
1799
3.85G
                            SET_IREF(pvalue);
1800
3.85G
                            goto top;
1801
4.09G
                        }
1802
                        /* default can't happen here */
1803
34.9G
                }
1804
34.9G
            }
1805
61.1G
    }
1806
    /* Literal type, just push it. */
1807
11.0G
    if (iosp >= ostop)
1808
11.0G
        return_with_stackoverflow_iref();
1809
11.0G
    ++iosp;
1810
11.0G
    ref_assign_inline(iosp, IREF);
1811
11.1G
  bot:next();
1812
6.58G
  out:                          /* At most 1 more token in the current procedure. */
1813
    /* (We already decremented icount.) */
1814
6.58G
    if (!icount) {
1815
        /* Pop the execution stack for tail recursion. */
1816
3.22G
        iesp--;
1817
3.22G
        iref_packed = IREF_NEXT(iref_packed);
1818
3.22G
        goto top;
1819
3.22G
    }
1820
14.5G
  up:if (--(*ticks_left) < 0)
1821
168k
        goto slice;
1822
    /* See if there is anything left on the execution stack. */
1823
14.5G
    if (!r_is_proc(iesp)) {
1824
5.73G
        SET_IREF(iesp--);
1825
5.73G
        icount = 0;
1826
5.73G
        goto top;
1827
5.73G
    }
1828
8.81G
    SET_IREF(iesp->value.refs); /* next element of array */
1829
8.81G
    icount = r_size(iesp) - 1;
1830
8.81G
    if (icount <= 0) {          /* <= 1 more elements */
1831
1.36G
        iesp--;                 /* pop, or tail recursion */
1832
1.36G
        if (icount < 0)
1833
28.9M
            goto up;
1834
1.36G
    }
1835
8.79G
    goto top;
1836
8.79G
  sched:                        /* We've just called a scheduling procedure. */
1837
    /* The interpreter state is in memory; iref is not current. */
1838
500k
    if (code < 0) {
1839
0
        set_error(code);
1840
        /*
1841
         * We need a real object to return as the error object.
1842
         * (It only has to last long enough to store in
1843
         * *perror_object.)
1844
         */
1845
0
        make_null_proc(&ierror.full);
1846
0
        SET_IREF(ierror.obj = &ierror.full);
1847
0
        goto error_exit;
1848
0
    }
1849
    /* Reload state information from memory. */
1850
500k
    iosp = osp;
1851
500k
    iesp = esp;
1852
500k
    goto up;
1853
#if 0                           /****** ****** ***** */
1854
  sst:                          /* Time-slice, but push the current object first. */
1855
    store_state(iesp);
1856
    if (iesp >= estop)
1857
        return_with_error_iref(gs_error_execstackoverflow);
1858
    iesp++;
1859
    ref_assign_inline(iesp, iref);
1860
#endif /****** ****** ***** */
1861
500k
  slice:                        /* It's time to time-slice or garbage collect. */
1862
    /* iref is not live, so we don't need to do a store_state. */
1863
500k
    osp = iosp;
1864
500k
    esp = iesp;
1865
    /* If *ticks_left <= -100, we need to GC now. */
1866
500k
    if ((*ticks_left) <= -100) {   /* We need to garbage collect now. */
1867
4.00k
        *pi_ctx_p = i_ctx_p;
1868
4.00k
        code = interp_reclaim(pi_ctx_p, -1);
1869
4.00k
        i_ctx_p = *pi_ctx_p;
1870
4.00k
    } else
1871
496k
        code = 0;
1872
500k
    *ticks_left = i_ctx_p->time_slice_ticks;
1873
500k
    set_code_on_interrupt(imemory, &code);
1874
500k
    goto sched;
1875
1876
    /* Error exits. */
1877
1878
49.5M
  rweci:
1879
49.5M
    ierror.code = code;
1880
52.2M
  rwei:
1881
52.2M
    ierror.obj = IREF;
1882
52.3M
  rwe:
1883
52.3M
    if (!r_is_packed(iref_packed))
1884
5.35M
        store_state(iesp);
1885
46.9M
    else {
1886
        /*
1887
         * We need a real object to return as the error object.
1888
         * (It only has to last long enough to store in *perror_object.)
1889
         */
1890
46.9M
        packed_get(imemory, (const ref_packed *)ierror.obj, &ierror.full);
1891
46.9M
        store_state_short(iesp);
1892
46.9M
        if (IREF == ierror.obj)
1893
46.9M
            SET_IREF(&ierror.full);
1894
46.9M
        ierror.obj = &ierror.full;
1895
46.9M
    }
1896
52.3M
  error_exit:
1897
52.3M
    if (GS_ERROR_IS_INTERRUPT(ierror.code)) {      /* We must push the current object being interpreted */
1898
        /* back on the e-stack so it will be re-executed. */
1899
        /* Currently, this is always an executable operator, */
1900
        /* but it might be something else someday if we check */
1901
        /* for interrupts in the interpreter loop itself. */
1902
0
        if (iesp >= estop)
1903
0
            ierror.code = gs_error_execstackoverflow;
1904
0
        else {
1905
0
            iesp++;
1906
0
            ref_assign_inline(iesp, IREF);
1907
0
        }
1908
0
    }
1909
52.3M
    esp = iesp;
1910
52.3M
    osp = iosp;
1911
52.3M
    ref_assign_inline(perror_object, ierror.obj);
1912
#ifdef DEBUG
1913
    if (ierror.code == gs_error_InterpreterExit) {
1914
        /* Do not call gs_log_error to reduce the noise. */
1915
        return gs_error_InterpreterExit;
1916
    }
1917
#endif
1918
52.3M
    return gs_log_error(ierror.code, __FILE__, ierror.line);
1919
52.3M
}
1920
1921
/* Pop the bookkeeping information for a normal exit from a t_oparray. */
1922
static int
1923
oparray_pop(i_ctx_t *i_ctx_p)
1924
1.81G
{
1925
1.81G
    esp -= 4;
1926
1.81G
    return o_pop_estack;
1927
1.81G
}
1928
1929
/* Restore the stack pointers after an error inside a t_oparray procedure. */
1930
/* This procedure is called only from pop_estack. */
1931
static int
1932
oparray_cleanup(i_ctx_t *i_ctx_p)
1933
45.6M
{                               /* esp points just below the cleanup procedure. */
1934
45.6M
    es_ptr ep = esp;
1935
45.6M
    uint ocount_old = (uint) ep[3].value.intval;
1936
45.6M
    uint dcount_old = (uint) ep[4].value.intval;
1937
45.6M
    uint ocount = ref_stack_count(&o_stack);
1938
45.6M
    uint dcount = ref_stack_count(&d_stack);
1939
1940
45.6M
    if (ocount > ocount_old)
1941
298k
        ref_stack_pop(&o_stack, ocount - ocount_old);
1942
45.6M
    if (dcount > dcount_old) {
1943
277k
        ref_stack_pop(&d_stack, dcount - dcount_old);
1944
277k
        dict_set_top();
1945
277k
    }
1946
45.6M
    return 0;
1947
45.6M
}
1948
1949
/* Don't restore the stack pointers. */
1950
static int
1951
oparray_no_cleanup(i_ctx_t *i_ctx_p)
1952
0
{
1953
0
    return 0;
1954
0
}
1955
1956
/* Find the innermost oparray. */
1957
static ref *
1958
oparray_find(i_ctx_t *i_ctx_p)
1959
357k
{
1960
357k
    long i;
1961
357k
    ref *ep;
1962
1963
4.81M
    for (i = 0; (ep = ref_stack_index(&e_stack, i)) != 0; ++i) {
1964
4.81M
        if (r_is_estack_mark(ep) &&
1965
4.81M
            (ep->value.opproc == oparray_cleanup ||
1966
714k
             ep->value.opproc == oparray_no_cleanup)
1967
4.81M
            )
1968
357k
            return ep;
1969
4.81M
    }
1970
0
    return 0;
1971
357k
}
1972
1973
/* <errorobj> <obj> .errorexec ... */
1974
/* Execute an object, substituting errorobj for the 'command' if an error */
1975
/* occurs during the execution.  Cf .execfile (in zfile.c). */
1976
static int
1977
zerrorexec(i_ctx_t *i_ctx_p)
1978
136M
{
1979
136M
    os_ptr op = osp;
1980
136M
    int code;
1981
1982
136M
    check_op(2);
1983
136M
    check_estack(4);            /* mark/cleanup, errobj, pop, obj */
1984
136M
    push_mark_estack(es_other, errorexec_cleanup);
1985
136M
    *++esp = op[-1];
1986
136M
    push_op_estack(errorexec_pop);
1987
136M
    code = zexec(i_ctx_p);
1988
136M
    if (code >= 0)
1989
136M
        pop(1);
1990
0
    else
1991
0
        esp -= 3;               /* undo our additions to estack */
1992
136M
    return code;
1993
136M
}
1994
1995
/* - .finderrorobject <errorobj> true */
1996
/* - .finderrorobject false */
1997
/* If we are within an .errorexec or oparray, return the error object */
1998
/* and true, otherwise return false. */
1999
static int
2000
zfinderrorobject(i_ctx_t *i_ctx_p)
2001
274k
{
2002
274k
    os_ptr op = osp;
2003
274k
    ref errobj;
2004
2005
274k
    if (errorexec_find(i_ctx_p, &errobj)) {
2006
274k
        push(2);
2007
274k
        op[-1] = errobj;
2008
274k
        make_true(op);
2009
274k
    } else {
2010
0
        push(1);
2011
0
        make_false(op);
2012
0
    }
2013
274k
    return 0;
2014
274k
}
2015
2016
/*
2017
 * Find the innermost .errorexec or oparray.  If there is an oparray, or a
2018
 * .errorexec with errobj != null, store it in *perror_object and return 1,
2019
 * otherwise return 0;
2020
 */
2021
int
2022
errorexec_find(i_ctx_t *i_ctx_p, ref *perror_object)
2023
50.6M
{
2024
50.6M
    long i;
2025
50.6M
    const ref *ep;
2026
2027
658M
    for (i = 0; (ep = ref_stack_index(&e_stack, i)) != 0; ++i) {
2028
657M
        if (r_is_estack_mark(ep)) {
2029
95.6M
            if (ep->value.opproc == oparray_cleanup) {
2030
                /* See oppr: above. */
2031
48.2M
                uint opindex = (uint)ep[1].value.intval;
2032
48.2M
                if (opindex == 0) /* internal operator, ignore */
2033
0
                    continue;
2034
48.2M
                op_index_ref(imemory, opindex, perror_object);
2035
48.2M
                return 1;
2036
48.2M
            }
2037
47.3M
            if (ep->value.opproc == oparray_no_cleanup)
2038
0
                return 0;       /* protection disabled */
2039
47.3M
            if (ep->value.opproc == errorexec_cleanup) {
2040
1.05M
                if (r_has_type(ep + 1, t_null))
2041
312k
                    return 0;
2042
739k
                *perror_object = ep[1]; /* see .errorexec above */
2043
739k
                return 1;
2044
1.05M
            }
2045
47.3M
        }
2046
657M
    }
2047
1.33M
    return 0;
2048
50.6M
}
2049
2050
/* Pop the bookkeeping information on a normal exit from .errorexec. */
2051
static int
2052
errorexec_pop(i_ctx_t *i_ctx_p)
2053
136M
{
2054
136M
    esp -= 2;
2055
136M
    return o_pop_estack;
2056
136M
}
2057
2058
/* Clean up when unwinding the stack on an error.  (No action needed.) */
2059
static int
2060
errorexec_cleanup(i_ctx_t *i_ctx_p)
2061
309k
{
2062
309k
    return 0;
2063
309k
}
2064
2065
/* <bool> .setstackprotect - */
2066
/* Set whether to protect the stack for the innermost oparray. */
2067
static int
2068
zsetstackprotect(i_ctx_t *i_ctx_p)
2069
357k
{
2070
357k
    os_ptr op = osp;
2071
357k
    ref *ep = oparray_find(i_ctx_p);
2072
2073
357k
    check_type(*op, t_boolean);
2074
357k
    if (ep == 0)
2075
0
        return_error(gs_error_rangecheck);
2076
357k
    ep->value.opproc =
2077
357k
        (op->value.boolval ? oparray_cleanup : oparray_no_cleanup);
2078
357k
    pop(1);
2079
357k
    return 0;
2080
357k
}
2081
2082
/* - .currentstackprotect <bool> */
2083
/* Return the stack protection status. */
2084
static int
2085
zcurrentstackprotect(i_ctx_t *i_ctx_p)
2086
0
{
2087
0
    os_ptr op = osp;
2088
0
    ref *ep = oparray_find(i_ctx_p);
2089
2090
0
    if (ep == 0)
2091
0
        return_error(gs_error_rangecheck);
2092
0
    push(1);
2093
0
    make_bool(op, ep->value.opproc == oparray_cleanup);
2094
0
    return 0;
2095
0
}
2096
2097
static int
2098
zactonuel(i_ctx_t *i_ctx_p)
2099
89.2k
{
2100
89.2k
    os_ptr op = osp;
2101
2102
89.2k
    push(1);
2103
89.2k
    make_bool(op, !!gs_lib_ctx_get_act_on_uel((gs_memory_t *)(i_ctx_p->memory.current)));
2104
89.2k
    return 0;
2105
89.2k
}