1 /* Copyright (C) 1989, 2000, 2001 Aladdin Enterprises. All rights reserved. 2 3 This software is provided AS-IS with no warranty, either express or 4 implied. 5 6 This software is distributed under license and may not be copied, 7 modified or distributed except as expressly authorized under the terms 8 of the license contained in the file LICENSE in this distribution. 9 10 For more information about licensing, please refer to 11 http://www.ghostscript.com/licensing/. For information on 12 commercial licensing, go to http://www.artifex.com/licensing/ or 13 contact Artifex Software, Inc., 101 Lucas Valley Road #110, 14 San Rafael, CA 94903, U.S.A., +1(415)492-9861. 15 */ 16 17 /* $Id: interp.c,v 1.20 2004/09/03 20:23:10 ray Exp $ */ 18 /* Ghostscript language interpreter */ 19 #include "memory_.h" 20 #include "string_.h" 21 #include "ghost.h" 22 #include "gsstruct.h" /* for iastruct.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 e_RemapColor */ 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 "dstack.h" 47 #include "files.h" /* for file_check_read */ 48 #include "oper.h" 49 #include "store.h" 50 #include "gpcheck.h" 51 52 /* 53 * We may or may not optimize the handling of the special fast operators 54 * in packed arrays. If we do this, they run much faster when packed, but 55 * slightly slower when not packed. 56 */ 57 #define PACKED_SPECIAL_OPS 1 58 59 /* 60 * Pseudo-operators (procedures of type t_oparray) record 61 * the operand and dictionary stack pointers, and restore them if an error 62 * occurs during the execution of the procedure and if the procedure hasn't 63 * (net) decreased the depth of the stack. While this obviously doesn't 64 * do all the work of restoring the state if a pseudo-operator gets an 65 * error, it's a big help. The only downside is that pseudo-operators run 66 * a little slower. 67 */ 68 69 /* GC descriptors for stacks */ 70 extern_st(st_ref_stack); 71 public_st_dict_stack(); 72 public_st_exec_stack(); 73 public_st_op_stack(); 74 75 /* 76 * The procedure to call if an operator requests rescheduling. 77 * This causes an error unless the context machinery has been installed. 78 */ 79 private int 80 no_reschedule(i_ctx_t **pi_ctx_p) 81 { 82 return_error(e_invalidcontext); 83 } 84 int (*gs_interp_reschedule_proc)(i_ctx_t **) = no_reschedule; 85 86 /* 87 * The procedure to call for time-slicing. 88 * This is a no-op unless the context machinery has been installed. 89 */ 90 int (*gs_interp_time_slice_proc)(i_ctx_t **) = 0; 91 92 /* 93 * The number of interpreter "ticks" between calls on the time_slice_proc. 94 * Currently, the clock ticks before each operator, and at each 95 * procedure return. 96 */ 97 int gs_interp_time_slice_ticks = 0x7fff; 98 99 /* 100 * Apply an operator. When debugging, we route all operator calls 101 * through a procedure. 102 */ 103 #ifdef DEBUG 104 private int 105 call_operator(op_proc_t op_proc, i_ctx_t *i_ctx_p) 106 { 107 int code = op_proc(i_ctx_p); 108 109 return code; 110 } 111 #else 112 # define call_operator(proc, p) ((*(proc))(p)) 113 #endif 114 115 /* Define debugging statistics. */ 116 #ifdef DEBUG 117 struct stats_interp_s { 118 long top; 119 long lit, lit_array, exec_array, exec_operator, exec_name; 120 long x_add, x_def, x_dup, x_exch, x_if, x_ifelse, 121 x_index, x_pop, x_roll, x_sub; 122 long find_name, name_lit, name_proc, name_oparray, name_operator; 123 long p_full, p_exec_operator, p_exec_oparray, p_exec_non_x_operator, 124 p_integer, p_lit_name, p_exec_name; 125 long p_find_name, p_name_lit, p_name_proc; 126 } stats_interp; 127 # define INCR(v) (++(stats_interp.v)) 128 #else 129 # define INCR(v) DO_NOTHING 130 #endif 131 132 /* Forward references */ 133 private int estack_underflow(i_ctx_t *); 134 private int interp(i_ctx_t **, const ref *, ref *); 135 private int interp_exit(i_ctx_t *); 136 private void set_gc_signal(i_ctx_t *, int *, int); 137 private int copy_stack(i_ctx_t *, const ref_stack_t *, ref *); 138 private int oparray_pop(i_ctx_t *); 139 private int oparray_cleanup(i_ctx_t *); 140 private int zsetstackprotect(i_ctx_t *); 141 private int zcurrentstackprotect(i_ctx_t *); 142 143 /* Stack sizes */ 144 145 /* The maximum stack sizes may all be set in the makefile. */ 146 147 /* 148 * Define the initial maximum size of the operand stack (MaxOpStack 149 * user parameter). 150 */ 151 #ifndef MAX_OSTACK 152 # define MAX_OSTACK 800 153 #endif 154 /* 155 * The minimum block size for extending the operand stack is the larger of: 156 * - the maximum number of parameters to an operator 157 * (currently setcolorscreen, with 12 parameters); 158 * - the maximum number of values pushed by an operator 159 * (currently setcolortransfer, which calls zcolor_remap_one 4 times 160 * and therefore pushes 16 values). 161 */ 162 #define MIN_BLOCK_OSTACK 16 163 const int gs_interp_max_op_num_args = MIN_BLOCK_OSTACK; /* for iinit.c */ 164 165 /* 166 * Define the initial maximum size of the execution stack (MaxExecStack 167 * user parameter). 168 */ 169 #ifndef MAX_ESTACK 170 # define MAX_ESTACK 5000 171 #endif 172 /* 173 * The minimum block size for extending the execution stack is the largest 174 * size of a contiguous block surrounding an e-stack mark. (At least, 175 * that's what the minimum value would be if we supported multi-block 176 * estacks, which we currently don't.) Currently, the largest such block is 177 * the one created for text processing, which is 8 (snumpush) slots. 178 */ 179 #define MIN_BLOCK_ESTACK 8 180 /* 181 * If we get an e-stack overflow, we need to cut it back far enough to 182 * have some headroom for executing the error procedure. 183 */ 184 #define ES_HEADROOM 20 185 186 /* 187 * Define the initial maximum size of the dictionary stack (MaxDictStack 188 * user parameter). Again, this is also currently the block size for 189 * extending the d-stack. 190 */ 191 #ifndef MAX_DSTACK 192 # define MAX_DSTACK 20 193 #endif 194 /* 195 * The minimum block size for extending the dictionary stack is the number 196 * of permanent entries on the dictionary stack, currently 3. 197 */ 198 #define MIN_BLOCK_DSTACK 3 199 200 /* See estack.h for a description of the execution stack. */ 201 202 /* The logic for managing icount and iref below assumes that */ 203 /* there are no control operators which pop and then push */ 204 /* information on the execution stack. */ 205 206 /* Stacks */ 207 extern_st(st_ref_stack); 208 #define OS_GUARD_UNDER 10 209 #define OS_GUARD_OVER 10 210 #define OS_REFS_SIZE(body_size)\ 211 (stack_block_refs + OS_GUARD_UNDER + (body_size) + OS_GUARD_OVER) 212 213 #define ES_GUARD_UNDER 1 214 #define ES_GUARD_OVER 10 215 #define ES_REFS_SIZE(body_size)\ 216 (stack_block_refs + ES_GUARD_UNDER + (body_size) + ES_GUARD_OVER) 217 218 #define DS_REFS_SIZE(body_size)\ 219 (stack_block_refs + (body_size)) 220 221 /* Extended types. The interpreter may replace the type of operators */ 222 /* in procedures with these, to speed up the interpretation loop. */ 223 /****** NOTE: If you add or change entries in this list, */ 224 /****** you must change the three dispatches in the interpreter loop. */ 225 /* The operator procedures are declared in opextern.h. */ 226 #define tx_op t_next_index 227 typedef enum { 228 tx_op_add = tx_op, 229 tx_op_def, 230 tx_op_dup, 231 tx_op_exch, 232 tx_op_if, 233 tx_op_ifelse, 234 tx_op_index, 235 tx_op_pop, 236 tx_op_roll, 237 tx_op_sub, 238 tx_next_op 239 } special_op_types; 240 241 #define num_special_ops ((int)tx_next_op - tx_op) 242 const int gs_interp_num_special_ops = num_special_ops; /* for iinit.c */ 243 const int tx_next_index = tx_next_op; 244 245 /* 246 * Define the interpreter operators, which include the extended-type 247 * operators defined in the list above. NOTE: if the size of this table 248 * ever exceeds 15 real entries, it will have to be split. 249 */ 250 const op_def interp_op_defs[] = { 251 /* 252 * The very first entry, which corresponds to operator index 0, 253 * must not contain an actual operator. 254 */ 255 op_def_begin_dict("systemdict"), 256 /* 257 * The next entries must be the extended-type operators, in the 258 * correct order. 259 */ 260 {"2add", zadd}, 261 {"2def", zdef}, 262 {"1dup", zdup}, 263 {"2exch", zexch}, 264 {"2if", zif}, 265 {"3ifelse", zifelse}, 266 {"1index", zindex}, 267 {"1pop", zpop}, 268 {"2roll", zroll}, 269 {"2sub", zsub}, 270 /* 271 * The remaining entries are internal operators. 272 */ 273 {"0.currentstackprotect", zcurrentstackprotect}, 274 {"1.setstackprotect", zsetstackprotect}, 275 {"0%interp_exit", interp_exit}, 276 {"0%oparray_pop", oparray_pop}, 277 op_def_end(0) 278 }; 279 280 #define make_null_proc(pref)\ 281 make_empty_const_array(pref, a_executable + a_readonly) 282 283 /* Initialize the interpreter. */ 284 int 285 gs_interp_init(i_ctx_t **pi_ctx_p, const ref *psystem_dict, 286 gs_dual_memory_t *dmem) 287 { 288 /* Create and initialize a context state. */ 289 gs_context_state_t *pcst = 0; 290 int code = context_state_alloc(&pcst, psystem_dict, dmem); 291 292 if (code >= 0) 293 code = context_state_load(pcst); 294 if (code < 0) 295 lprintf1("Fatal error %d in gs_interp_init!", code); 296 *pi_ctx_p = pcst; 297 return code; 298 } 299 /* 300 * Create initial stacks for the interpreter. 301 * We export this for creating new contexts. 302 */ 303 int 304 gs_interp_alloc_stacks(gs_ref_memory_t *mem, gs_context_state_t * pcst) 305 { 306 gs_ref_memory_t *smem = 307 (gs_ref_memory_t *)gs_memory_stable((gs_memory_t *)mem); 308 ref stk; 309 310 #define REFS_SIZE_OSTACK OS_REFS_SIZE(MAX_OSTACK) 311 #define REFS_SIZE_ESTACK ES_REFS_SIZE(MAX_ESTACK) 312 #define REFS_SIZE_DSTACK DS_REFS_SIZE(MAX_DSTACK) 313 gs_alloc_ref_array(smem, &stk, 0, 314 REFS_SIZE_OSTACK + REFS_SIZE_ESTACK + 315 REFS_SIZE_DSTACK, "gs_interp_alloc_stacks"); 316 317 { 318 ref_stack_t *pos = &pcst->op_stack.stack; 319 320 r_set_size(&stk, REFS_SIZE_OSTACK); 321 ref_stack_init(pos, &stk, OS_GUARD_UNDER, OS_GUARD_OVER, NULL, 322 smem, NULL); 323 ref_stack_set_error_codes(pos, e_stackunderflow, e_stackoverflow); 324 ref_stack_set_max_count(pos, MAX_OSTACK); 325 stk.value.refs += REFS_SIZE_OSTACK; 326 } 327 328 { 329 ref_stack_t *pes = &pcst->exec_stack.stack; 330 ref euop; 331 332 r_set_size(&stk, REFS_SIZE_ESTACK); 333 make_oper(&euop, 0, estack_underflow); 334 ref_stack_init(pes, &stk, ES_GUARD_UNDER, ES_GUARD_OVER, &euop, 335 smem, NULL); 336 ref_stack_set_error_codes(pes, e_ExecStackUnderflow, 337 e_execstackoverflow); 338 /**************** E-STACK EXPANSION IS NYI. ****************/ 339 ref_stack_allow_expansion(pes, false); 340 ref_stack_set_max_count(pes, MAX_ESTACK); 341 stk.value.refs += REFS_SIZE_ESTACK; 342 } 343 344 { 345 ref_stack_t *pds = &pcst->dict_stack.stack; 346 347 r_set_size(&stk, REFS_SIZE_DSTACK); 348 ref_stack_init(pds, &stk, 0, 0, NULL, smem, NULL); 349 ref_stack_set_error_codes(pds, e_dictstackunderflow, 350 e_dictstackoverflow); 351 ref_stack_set_max_count(pds, MAX_DSTACK); 352 } 353 354 #undef REFS_SIZE_OSTACK 355 #undef REFS_SIZE_ESTACK 356 #undef REFS_SIZE_DSTACK 357 return 0; 358 } 359 /* 360 * Free the stacks when destroying a context. This is the inverse of 361 * create_stacks. 362 */ 363 void 364 gs_interp_free_stacks(gs_ref_memory_t * smem, gs_context_state_t * pcst) 365 { 366 /* Free the stacks in inverse order of allocation. */ 367 ref_stack_release(&pcst->dict_stack.stack); 368 ref_stack_release(&pcst->exec_stack.stack); 369 ref_stack_release(&pcst->op_stack.stack); 370 } 371 void 372 gs_interp_reset(i_ctx_t *i_ctx_p) 373 { /* Reset the stacks. */ 374 ref_stack_clear(&o_stack); 375 ref_stack_clear(&e_stack); 376 esp++; 377 make_oper(esp, 0, interp_exit); 378 ref_stack_pop_to(&d_stack, min_dstack_size); 379 dict_set_top(); 380 } 381 /* Report an e-stack block underflow. The bottom guard slots of */ 382 /* e-stack blocks contain a pointer to this procedure. */ 383 private int 384 estack_underflow(i_ctx_t *i_ctx_p) 385 { 386 return e_ExecStackUnderflow; 387 } 388 389 /* 390 * Create an operator during initialization. 391 * If operator is hard-coded into the interpreter, 392 * assign it a special type and index. 393 */ 394 void 395 gs_interp_make_oper(ref * opref, op_proc_t proc, int idx) 396 { 397 int i; 398 399 for (i = num_special_ops; i > 0 && proc != interp_op_defs[i].proc; --i) 400 DO_NOTHING; 401 if (i > 0) 402 make_tasv(opref, tx_op + (i - 1), a_executable, i, opproc, proc); 403 else 404 make_tasv(opref, t_operator, a_executable, idx, opproc, proc); 405 } 406 407 /* 408 * Call the garbage collector, updating the context pointer properly. 409 */ 410 int 411 interp_reclaim(i_ctx_t **pi_ctx_p, int space) 412 { 413 i_ctx_t *i_ctx_p = *pi_ctx_p; 414 gs_gc_root_t ctx_root; 415 int code; 416 417 gs_register_struct_root(imemory_system, &ctx_root, 418 (void **)pi_ctx_p, "interp_reclaim(pi_ctx_p)"); 419 code = (*idmemory->reclaim)(idmemory, space); 420 i_ctx_p = *pi_ctx_p; /* may have moved */ 421 gs_unregister_root(imemory_system, &ctx_root, "interp_reclaim(pi_ctx_p)"); 422 return code; 423 } 424 425 /* 426 * Invoke the interpreter. If execution completes normally, return 0. 427 * If an error occurs, the action depends on user_errors as follows: 428 * user_errors < 0: always return an error code. 429 * user_errors >= 0: let the PostScript machinery handle all errors. 430 * (This will eventually result in a fatal error if no 'stopped' 431 * is active.) 432 * In case of a quit or a fatal error, also store the exit code. 433 * Set *perror_object to null or the error object. 434 */ 435 private int gs_call_interp(i_ctx_t **, ref *, int, int *, ref *); 436 int 437 gs_interpret(i_ctx_t **pi_ctx_p, ref * pref, int user_errors, int *pexit_code, 438 ref * perror_object) 439 { 440 i_ctx_t *i_ctx_p = *pi_ctx_p; 441 gs_gc_root_t error_root; 442 int code; 443 444 gs_register_ref_root(imemory_system, &error_root, 445 (void **)&perror_object, "gs_interpret"); 446 code = gs_call_interp(pi_ctx_p, pref, user_errors, pexit_code, 447 perror_object); 448 i_ctx_p = *pi_ctx_p; 449 gs_unregister_root(imemory_system, &error_root, "gs_interpret"); 450 /* Avoid a dangling reference to a stack-allocated GC signal. */ 451 set_gc_signal(i_ctx_p, NULL, 0); 452 return code; 453 } 454 private int 455 gs_call_interp(i_ctx_t **pi_ctx_p, ref * pref, int user_errors, 456 int *pexit_code, ref * perror_object) 457 { 458 ref *epref = pref; 459 ref doref; 460 ref *perrordict; 461 ref error_name; 462 int code, ccode; 463 ref saref; 464 int gc_signal = 0; 465 i_ctx_t *i_ctx_p = *pi_ctx_p; 466 467 *pexit_code = 0; 468 ialloc_reset_requested(idmemory); 469 again: 470 /* Avoid a dangling error object that might get traced by a future GC. */ 471 make_null(perror_object); 472 o_stack.requested = e_stack.requested = d_stack.requested = 0; 473 while (gc_signal) { /* Some routine below triggered a GC. */ 474 gs_gc_root_t epref_root; 475 476 gc_signal = 0; 477 /* Make sure that doref will get relocated properly if */ 478 /* a garbage collection happens with epref == &doref. */ 479 gs_register_ref_root(imemory_system, &epref_root, 480 (void **)&epref, "gs_call_interp(epref)"); 481 code = interp_reclaim(pi_ctx_p, -1); 482 i_ctx_p = *pi_ctx_p; 483 gs_unregister_root(imemory_system, &epref_root, 484 "gs_call_interp(epref)"); 485 if (code < 0) 486 return code; 487 } 488 code = interp(pi_ctx_p, epref, perror_object); 489 i_ctx_p = *pi_ctx_p; 490 /* Prevent a dangling reference to the GC signal in ticks_left */ 491 /* in the frame of interp, but be prepared to do a GC if */ 492 /* an allocation in this routine asks for it. */ 493 set_gc_signal(i_ctx_p, &gc_signal, 1); 494 if (esp < esbot) /* popped guard entry */ 495 esp = esbot; 496 switch (code) { 497 case e_Fatal: 498 *pexit_code = 255; 499 return code; 500 case e_Quit: 501 *perror_object = osp[-1]; 502 *pexit_code = code = osp->value.intval; 503 osp -= 2; 504 return 505 (code == 0 ? e_Quit : 506 code < 0 && code > -100 ? code : e_Fatal); 507 case e_InterpreterExit: 508 return 0; 509 case e_ExecStackUnderflow: 510 /****** WRONG -- must keep mark blocks intact ******/ 511 ref_stack_pop_block(&e_stack); 512 doref = *perror_object; 513 epref = &doref; 514 goto again; 515 case e_VMreclaim: 516 /* Do the GC and continue. */ 517 code = interp_reclaim(pi_ctx_p, 518 (osp->value.intval == 2 ? 519 avm_global : avm_local)); 520 i_ctx_p = *pi_ctx_p; 521 /****** What if code < 0? ******/ 522 make_oper(&doref, 0, zpop); 523 epref = &doref; 524 goto again; 525 case e_NeedInput: 526 case e_NeedStdin: 527 case e_NeedStdout: 528 case e_NeedStderr: 529 return code; 530 } 531 /* Adjust osp in case of operand stack underflow */ 532 if (osp < osbot - 1) 533 osp = osbot - 1; 534 /* We have to handle stack over/underflow specially, because */ 535 /* we might be able to recover by adding or removing a block. */ 536 switch (code) { 537 case e_dictstackoverflow: 538 if (ref_stack_extend(&d_stack, d_stack.requested) >= 0) { 539 dict_set_top(); 540 doref = *perror_object; 541 epref = &doref; 542 goto again; 543 } 544 if (osp >= ostop) { 545 if ((ccode = ref_stack_extend(&o_stack, 1)) < 0) 546 return ccode; 547 } 548 ccode = copy_stack(i_ctx_p, &d_stack, &saref); 549 if (ccode < 0) 550 return ccode; 551 ref_stack_pop_to(&d_stack, min_dstack_size); 552 dict_set_top(); 553 *++osp = saref; 554 break; 555 case e_dictstackunderflow: 556 if (ref_stack_pop_block(&d_stack) >= 0) { 557 dict_set_top(); 558 doref = *perror_object; 559 epref = &doref; 560 goto again; 561 } 562 break; 563 case e_execstackoverflow: 564 /* We don't have to handle this specially: */ 565 /* The only places that could generate it */ 566 /* use check_estack, which does a ref_stack_extend, */ 567 /* so if we get this error, it's a real one. */ 568 if (osp >= ostop) { 569 if ((ccode = ref_stack_extend(&o_stack, 1)) < 0) 570 return ccode; 571 } 572 ccode = copy_stack(i_ctx_p, &e_stack, &saref); 573 if (ccode < 0) 574 return ccode; 575 { 576 uint count = ref_stack_count(&e_stack); 577 uint limit = ref_stack_max_count(&e_stack) - ES_HEADROOM; 578 579 if (count > limit) { 580 /* 581 * If there is an e-stack mark within MIN_BLOCK_ESTACK of 582 * the new top, cut the stack back to remove the mark. 583 */ 584 int skip = count - limit; 585 int i; 586 587 for (i = skip; i < skip + MIN_BLOCK_ESTACK; ++i) { 588 const ref *ep = ref_stack_index(&e_stack, i); 589 590 if (r_has_type_attrs(ep, t_null, a_executable)) { 591 skip = i + 1; 592 break; 593 } 594 } 595 pop_estack(i_ctx_p, skip); 596 } 597 } 598 *++osp = saref; 599 break; 600 case e_stackoverflow: 601 if (ref_stack_extend(&o_stack, o_stack.requested) >= 0) { /* We can't just re-execute the object, because */ 602 /* it might be a procedure being pushed as a */ 603 /* literal. We check for this case specially. */ 604 doref = *perror_object; 605 if (r_is_proc(&doref)) { 606 *++osp = doref; 607 make_null_proc(&doref); 608 } 609 epref = &doref; 610 goto again; 611 } 612 ccode = copy_stack(i_ctx_p, &o_stack, &saref); 613 if (ccode < 0) 614 return ccode; 615 ref_stack_clear(&o_stack); 616 *++osp = saref; 617 break; 618 case e_stackunderflow: 619 if (ref_stack_pop_block(&o_stack) >= 0) { 620 doref = *perror_object; 621 epref = &doref; 622 goto again; 623 } 624 break; 625 } 626 if (user_errors < 0) 627 return code; 628 if (gs_errorname(i_ctx_p, code, &error_name) < 0) 629 return code; /* out-of-range error code! */ 630 if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 || 631 dict_find(perrordict, &error_name, &epref) <= 0 632 ) 633 return code; /* error name not in errordict??? */ 634 doref = *epref; 635 epref = &doref; 636 /* Push the error object on the operand stack if appropriate. */ 637 if (!ERROR_IS_INTERRUPT(code)) 638 *++osp = *perror_object; 639 goto again; 640 } 641 private int 642 interp_exit(i_ctx_t *i_ctx_p) 643 { 644 return e_InterpreterExit; 645 } 646 647 /* Set the GC signal for all VMs. */ 648 private void 649 set_gc_signal(i_ctx_t *i_ctx_p, int *psignal, int value) 650 { 651 gs_memory_gc_status_t stat; 652 int i; 653 654 for (i = 0; i < countof(idmemory->spaces_indexed); i++) { 655 gs_ref_memory_t *mem = idmemory->spaces_indexed[i]; 656 gs_ref_memory_t *mem_stable; 657 658 if (mem == 0) 659 continue; 660 for (;; mem = mem_stable) { 661 mem_stable = (gs_ref_memory_t *) 662 gs_memory_stable((gs_memory_t *)mem); 663 gs_memory_gc_status(mem, &stat); 664 stat.psignal = psignal; 665 stat.signal_value = value; 666 gs_memory_set_gc_status(mem, &stat); 667 if (mem_stable == mem) 668 break; 669 } 670 } 671 } 672 673 /* Copy the contents of an overflowed stack into a (local) array. */ 674 private int 675 copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, ref * arr) 676 { 677 uint size = ref_stack_count(pstack); 678 uint save_space = ialloc_space(idmemory); 679 int code; 680 681 ialloc_set_space(idmemory, avm_local); 682 code = ialloc_ref_array(arr, a_all, size, "copy_stack"); 683 if (code >= 0) 684 code = ref_stack_store(pstack, arr, size, 0, 1, true, idmemory, 685 "copy_stack"); 686 ialloc_set_space(idmemory, save_space); 687 return code; 688 } 689 690 /* Get the name corresponding to an error number. */ 691 int 692 gs_errorname(i_ctx_t *i_ctx_p, int code, ref * perror_name) 693 { 694 ref *perrordict, *pErrorNames; 695 696 if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 || 697 dict_find_string(systemdict, "ErrorNames", &pErrorNames) <= 0 698 ) 699 return_error(e_undefined); /* errordict or ErrorNames not found?! */ 700 return array_get(imemory, pErrorNames, (long)(-code - 1), perror_name); 701 } 702 703 /* Store an error string in $error.errorinfo. */ 704 /* This routine is here because of the proximity to the error handler. */ 705 int 706 gs_errorinfo_put_string(i_ctx_t *i_ctx_p, const char *str) 707 { 708 ref rstr; 709 ref *pderror; 710 int code = string_to_ref(str, &rstr, iimemory, "gs_errorinfo_put_string"); 711 712 if (code < 0) 713 return code; 714 if (dict_find_string(systemdict, "$error", &pderror) <= 0 || 715 !r_has_type(pderror, t_dictionary) || 716 idict_put_string(pderror, "errorinfo", &rstr) < 0 717 ) 718 return_error(e_Fatal); 719 return 0; 720 } 721 722 /* Main interpreter. */ 723 /* If execution terminates normally, return e_InterpreterExit. */ 724 /* If an error occurs, leave the current object in *perror_object */ 725 /* and return a (negative) error code. */ 726 private int 727 interp(i_ctx_t **pi_ctx_p /* context for execution, updated if resched */, 728 const ref * pref /* object to interpret */, 729 ref * perror_object) 730 { 731 i_ctx_t *i_ctx_p = *pi_ctx_p; 732 /* 733 * Note that iref may actually be either a ref * or a ref_packed *. 734 * Certain DEC compilers assume that a ref * is ref-aligned even if it 735 * is cast to a short *, and generate code on this assumption, leading 736 * to "unaligned access" errors. For this reason, we declare 737 * iref_packed, and use a macro to cast it to the more aligned type 738 * where necessary (which is almost everywhere it is used). This may 739 * lead to compiler warnings about "cast increases alignment 740 * requirements", but this is less harmful than expensive traps at run 741 * time. 742 */ 743 register const ref_packed *iref_packed = (const ref_packed *)pref; 744 /* 745 * To make matters worse, some versions of gcc/egcs have a bug that 746 * leads them to assume that if iref_packed is EVER cast to a ref *, 747 * it is ALWAYS ref-aligned. We detect this in stdpre.h and provide 748 * the following workaround: 749 */ 750 #ifdef ALIGNMENT_ALIASING_BUG 751 const ref *iref_temp; 752 # define IREF (iref_temp = (const ref *)iref_packed, iref_temp) 753 #else 754 # define IREF ((const ref *)iref_packed) 755 #endif 756 #define SET_IREF(rp) (iref_packed = (const ref_packed *)(rp)) 757 register int icount = 0; /* # of consecutive tokens at iref */ 758 register os_ptr iosp = osp; /* private copy of osp */ 759 register es_ptr iesp = esp; /* private copy of esp */ 760 int code; 761 ref token; /* token read from file or string, */ 762 /* must be declared in this scope */ 763 register const ref *pvalue; 764 os_ptr whichp; 765 766 /* 767 * We have to make the error information into a struct; 768 * otherwise, the Watcom compiler will assign it to registers 769 * strictly on the basis of textual frequency. 770 * We also have to use ref_assign_inline everywhere, and 771 * avoid direct assignments of refs, so that esi and edi 772 * will remain available on Intel processors. 773 */ 774 struct interp_error_s { 775 int code; 776 int line; 777 const ref *obj; 778 ref full; 779 } ierror; 780 781 /* 782 * Get a pointer to the name table so that we can use the 783 * inline version of name_index_ref. 784 */ 785 const name_table *const int_nt = imemory->gs_lib_ctx->gs_name_table; 786 787 #define set_error(ecode)\ 788 { ierror.code = ecode; ierror.line = __LINE__; } 789 #define return_with_error(ecode, objp)\ 790 { set_error(ecode); ierror.obj = objp; goto rwe; } 791 #define return_with_error_iref(ecode)\ 792 { set_error(ecode); goto rwei; } 793 #define return_with_code_iref()\ 794 { ierror.line = __LINE__; goto rweci; } 795 #define return_with_error_code_op(nargs)\ 796 return_with_code_iref() 797 #define return_with_stackoverflow(objp)\ 798 { o_stack.requested = 1; return_with_error(e_stackoverflow, objp); } 799 #define return_with_stackoverflow_iref()\ 800 { o_stack.requested = 1; return_with_error_iref(e_stackoverflow); } 801 int ticks_left = gs_interp_time_slice_ticks; 802 803 /* 804 * If we exceed the VMThreshold, set ticks_left to -100 805 * to alert the interpreter that we need to garbage collect. 806 */ 807 set_gc_signal(i_ctx_p, &ticks_left, -100); 808 809 esfile_clear_cache(); 810 /* 811 * From here on, if icount > 0, iref and icount correspond 812 * to the top entry on the execution stack: icount is the count 813 * of sequential entries remaining AFTER the current one. 814 */ 815 #define IREF_NEXT(ip)\ 816 ((const ref_packed *)((const ref *)(ip) + 1)) 817 #define IREF_NEXT_EITHER(ip)\ 818 ( r_is_packed(ip) ? (ip) + 1 : IREF_NEXT(ip) ) 819 #define store_state(ep)\ 820 ( icount > 0 ? (ep->value.const_refs = IREF + 1, r_set_size(ep, icount)) : 0 ) 821 #define store_state_short(ep)\ 822 ( icount > 0 ? (ep->value.packed = iref_packed + 1, r_set_size(ep, icount)) : 0 ) 823 #define store_state_either(ep)\ 824 ( icount > 0 ? (ep->value.packed = IREF_NEXT_EITHER(iref_packed), r_set_size(ep, icount)) : 0 ) 825 #define next()\ 826 if ( --icount > 0 ) { iref_packed = IREF_NEXT(iref_packed); goto top; } else goto out 827 #define next_short()\ 828 if ( --icount <= 0 ) { if ( icount < 0 ) goto up; iesp--; }\ 829 ++iref_packed; goto top 830 #define next_either()\ 831 if ( --icount <= 0 ) { if ( icount < 0 ) goto up; iesp--; }\ 832 iref_packed = IREF_NEXT_EITHER(iref_packed); goto top 833 834 #if !PACKED_SPECIAL_OPS 835 # undef next_either 836 # define next_either() next() 837 # undef store_state_either 838 # define store_state_either(ep) store_state(ep) 839 #endif 840 841 /* We want to recognize executable arrays here, */ 842 /* so we push the argument on the estack and enter */ 843 /* the loop at the bottom. */ 844 if (iesp >= estop) 845 return_with_error(e_execstackoverflow, pref); 846 ++iesp; 847 ref_assign_inline(iesp, pref); 848 goto bot; 849 top: 850 /* 851 * This is the top of the interpreter loop. 852 * iref points to the ref being interpreted. 853 * Note that this might be an element of a packed array, 854 * not a real ref: we carefully arranged the first 16 bits of 855 * a ref and of a packed array element so they could be distinguished 856 * from each other. (See ghost.h and packed.h for more detail.) 857 */ 858 INCR(top); 859 #ifdef DEBUG 860 /* Do a little validation on the top o-stack entry. */ 861 if (iosp >= osbot && 862 (r_type(iosp) == t__invalid || r_type(iosp) >= tx_next_op) 863 ) { 864 lprintf("Invalid value on o-stack!\n"); 865 return_with_error_iref(e_Fatal); 866 } 867 if (gs_debug['I'] || 868 (gs_debug['i'] && 869 (r_is_packed(iref_packed) ? 870 r_packed_is_name(iref_packed) : 871 r_has_type(IREF, t_name))) 872 ) { 873 os_ptr save_osp = osp; /* avoid side-effects */ 874 es_ptr save_esp = esp; 875 876 osp = iosp; 877 esp = iesp; 878 dlprintf5("d%u,e%u<%u>0x%lx(%d): ", 879 ref_stack_count(&d_stack), ref_stack_count(&e_stack), 880 ref_stack_count(&o_stack), (ulong)IREF, icount); 881 debug_print_ref(imemory, IREF); 882 if (iosp >= osbot) { 883 dputs(" // "); 884 debug_print_ref(imemory, iosp); 885 } 886 dputc('\n'); 887 osp = save_osp; 888 esp = save_esp; 889 fflush(dstderr); 890 } 891 #endif 892 /* Objects that have attributes (arrays, dictionaries, files, and strings) */ 893 /* use lit and exec; other objects use plain and plain_exec. */ 894 #define lit(t) type_xe_value(t, a_execute) 895 #define exec(t) type_xe_value(t, a_execute + a_executable) 896 #define nox(t) type_xe_value(t, 0) 897 #define nox_exec(t) type_xe_value(t, a_executable) 898 #define plain(t) type_xe_value(t, 0) 899 #define plain_exec(t) type_xe_value(t, a_executable) 900 /* 901 * We have to populate enough cases of the switch statement to force 902 * some compilers to use a dispatch rather than a testing loop. 903 * What a nuisance! 904 */ 905 switch (r_type_xe(iref_packed)) { 906 /* Access errors. */ 907 #define cases_invalid()\ 908 case plain(t__invalid): case plain_exec(t__invalid) 909 cases_invalid(): 910 return_with_error_iref(e_Fatal); 911 #define cases_nox()\ 912 case nox_exec(t_array): case nox_exec(t_dictionary):\ 913 case nox_exec(t_file): case nox_exec(t_string):\ 914 case nox_exec(t_mixedarray): case nox_exec(t_shortarray) 915 cases_nox(): 916 return_with_error_iref(e_invalidaccess); 917 /* 918 * Literal objects. We have to enumerate all the types. 919 * In fact, we have to include some extra plain_exec entries 920 * just to populate the switch. We break them up into groups 921 * to avoid overflowing some preprocessors. 922 */ 923 #define cases_lit_1()\ 924 case lit(t_array): case nox(t_array):\ 925 case plain(t_boolean): case plain_exec(t_boolean):\ 926 case lit(t_dictionary): case nox(t_dictionary) 927 #define cases_lit_2()\ 928 case lit(t_file): case nox(t_file):\ 929 case plain(t_fontID): case plain_exec(t_fontID):\ 930 case plain(t_integer): case plain_exec(t_integer):\ 931 case plain(t_mark): case plain_exec(t_mark) 932 #define cases_lit_3()\ 933 case plain(t_name):\ 934 case plain(t_null):\ 935 case plain(t_oparray):\ 936 case plain(t_operator) 937 #define cases_lit_4()\ 938 case plain(t_real): case plain_exec(t_real):\ 939 case plain(t_save): case plain_exec(t_save):\ 940 case lit(t_string): case nox(t_string) 941 #define cases_lit_5()\ 942 case lit(t_mixedarray): case nox(t_mixedarray):\ 943 case lit(t_shortarray): case nox(t_shortarray):\ 944 case plain(t_device): case plain_exec(t_device):\ 945 case plain(t_struct): case plain_exec(t_struct):\ 946 case plain(t_astruct): case plain_exec(t_astruct) 947 /* Executable arrays are treated as literals in direct execution. */ 948 #define cases_lit_array()\ 949 case exec(t_array): case exec(t_mixedarray): case exec(t_shortarray) 950 cases_lit_1(): 951 cases_lit_2(): 952 cases_lit_3(): 953 cases_lit_4(): 954 cases_lit_5(): 955 INCR(lit); 956 break; 957 cases_lit_array(): 958 INCR(lit_array); 959 break; 960 /* Special operators. */ 961 case plain_exec(tx_op_add): 962 x_add: INCR(x_add); 963 if ((code = zop_add(iosp)) < 0) 964 return_with_error_code_op(2); 965 iosp--; 966 next_either(); 967 case plain_exec(tx_op_def): 968 x_def: INCR(x_def); 969 osp = iosp; /* sync o_stack */ 970 if ((code = zop_def(i_ctx_p)) < 0) 971 return_with_error_code_op(2); 972 iosp -= 2; 973 next_either(); 974 case plain_exec(tx_op_dup): 975 x_dup: INCR(x_dup); 976 if (iosp < osbot) 977 return_with_error_iref(e_stackunderflow); 978 if (iosp >= ostop) 979 return_with_stackoverflow_iref(); 980 iosp++; 981 ref_assign_inline(iosp, iosp - 1); 982 next_either(); 983 case plain_exec(tx_op_exch): 984 x_exch: INCR(x_exch); 985 if (iosp <= osbot) 986 return_with_error_iref(e_stackunderflow); 987 ref_assign_inline(&token, iosp); 988 ref_assign_inline(iosp, iosp - 1); 989 ref_assign_inline(iosp - 1, &token); 990 next_either(); 991 case plain_exec(tx_op_if): 992 x_if: INCR(x_if); 993 if (!r_has_type(iosp - 1, t_boolean)) 994 return_with_error_iref((iosp <= osbot ? 995 e_stackunderflow : e_typecheck)); 996 if (!r_is_proc(iosp)) 997 return_with_error_iref(check_proc_failed(iosp)); 998 if (!iosp[-1].value.boolval) { 999 iosp -= 2; 1000 next_either(); 1001 } 1002 if (iesp >= estop) 1003 return_with_error_iref(e_execstackoverflow); 1004 store_state_either(iesp); 1005 whichp = iosp; 1006 iosp -= 2; 1007 goto ifup; 1008 case plain_exec(tx_op_ifelse): 1009 x_ifelse: INCR(x_ifelse); 1010 if (!r_has_type(iosp - 2, t_boolean)) 1011 return_with_error_iref((iosp < osbot + 2 ? 1012 e_stackunderflow : e_typecheck)); 1013 if (!r_is_proc(iosp - 1)) 1014 return_with_error_iref(check_proc_failed(iosp - 1)); 1015 if (!r_is_proc(iosp)) 1016 return_with_error_iref(check_proc_failed(iosp)); 1017 if (iesp >= estop) 1018 return_with_error_iref(e_execstackoverflow); 1019 store_state_either(iesp); 1020 whichp = (iosp[-2].value.boolval ? iosp - 1 : iosp); 1021 iosp -= 3; 1022 /* Open code "up" for the array case(s) */ 1023 ifup:if ((icount = r_size(whichp) - 1) <= 0) { 1024 if (icount < 0) 1025 goto up; /* 0-element proc */ 1026 SET_IREF(whichp->value.refs); /* 1-element proc */ 1027 if (--ticks_left > 0) 1028 goto top; 1029 } 1030 ++iesp; 1031 /* Do a ref_assign, but also set iref. */ 1032 iesp->tas = whichp->tas; 1033 SET_IREF(iesp->value.refs = whichp->value.refs); 1034 if (--ticks_left > 0) 1035 goto top; 1036 goto slice; 1037 case plain_exec(tx_op_index): 1038 x_index: INCR(x_index); 1039 osp = iosp; /* zindex references o_stack */ 1040 if ((code = zindex(i_ctx_p)) < 0) 1041 return_with_error_code_op(1); 1042 next_either(); 1043 case plain_exec(tx_op_pop): 1044 x_pop: INCR(x_pop); 1045 if (iosp < osbot) 1046 return_with_error_iref(e_stackunderflow); 1047 iosp--; 1048 next_either(); 1049 case plain_exec(tx_op_roll): 1050 x_roll: INCR(x_roll); 1051 osp = iosp; /* zroll references o_stack */ 1052 if ((code = zroll(i_ctx_p)) < 0) 1053 return_with_error_code_op(2); 1054 iosp -= 2; 1055 next_either(); 1056 case plain_exec(tx_op_sub): 1057 x_sub: INCR(x_sub); 1058 if ((code = zop_sub(iosp)) < 0) 1059 return_with_error_code_op(2); 1060 iosp--; 1061 next_either(); 1062 /* Executable types. */ 1063 case plain_exec(t_null): 1064 goto bot; 1065 case plain_exec(t_oparray): 1066 /* Replace with the definition and go again. */ 1067 INCR(exec_array); 1068 pvalue = IREF->value.const_refs; 1069 opst: /* Prepare to call a t_oparray procedure in *pvalue. */ 1070 store_state(iesp); 1071 oppr: /* Record the stack depths in case of failure. */ 1072 if (iesp >= estop - 3) 1073 return_with_error_iref(e_execstackoverflow); 1074 iesp += 4; 1075 osp = iosp; /* ref_stack_count_inline needs this */ 1076 make_mark_estack(iesp - 3, es_other, oparray_cleanup); 1077 make_int(iesp - 2, ref_stack_count_inline(&o_stack)); 1078 make_int(iesp - 1, ref_stack_count_inline(&d_stack)); 1079 make_op_estack(iesp, oparray_pop); 1080 goto pr; 1081 prst: /* Prepare to call the procedure (array) in *pvalue. */ 1082 store_state(iesp); 1083 pr: /* Call the array in *pvalue. State has been stored. */ 1084 if ((icount = r_size(pvalue) - 1) <= 0) { 1085 if (icount < 0) 1086 goto up; /* 0-element proc */ 1087 SET_IREF(pvalue->value.refs); /* 1-element proc */ 1088 if (--ticks_left > 0) 1089 goto top; 1090 } 1091 if (iesp >= estop) 1092 return_with_error_iref(e_execstackoverflow); 1093 ++iesp; 1094 /* Do a ref_assign, but also set iref. */ 1095 iesp->tas = pvalue->tas; 1096 SET_IREF(iesp->value.refs = pvalue->value.refs); 1097 if (--ticks_left > 0) 1098 goto top; 1099 goto slice; 1100 case plain_exec(t_operator): 1101 INCR(exec_operator); 1102 if (--ticks_left <= 0) { /* The following doesn't work, */ 1103 /* and I can't figure out why. */ 1104 /****** goto sst; ******/ 1105 } 1106 esp = iesp; /* save for operator */ 1107 osp = iosp; /* ditto */ 1108 /* Operator routines take osp as an argument. */ 1109 /* This is just a convenience, since they adjust */ 1110 /* osp themselves to reflect the results. */ 1111 /* Operators that (net) push information on the */ 1112 /* operand stack must check for overflow: */ 1113 /* this normally happens automatically through */ 1114 /* the push macro (in oper.h). */ 1115 /* Operators that do not typecheck their operands, */ 1116 /* or take a variable number of arguments, */ 1117 /* must check explicitly for stack underflow. */ 1118 /* (See oper.h for more detail.) */ 1119 /* Note that each case must set iosp = osp: */ 1120 /* this is so we can switch on code without having to */ 1121 /* store it and reload it (for dumb compilers). */ 1122 switch (code = call_operator(real_opproc(IREF), i_ctx_p)) { 1123 case 0: /* normal case */ 1124 case 1: /* alternative success case */ 1125 iosp = osp; 1126 next(); 1127 case o_push_estack: /* store the state and go to up */ 1128 store_state(iesp); 1129 opush:iosp = osp; 1130 iesp = esp; 1131 if (--ticks_left > 0) 1132 goto up; 1133 goto slice; 1134 case o_pop_estack: /* just go to up */ 1135 opop:iosp = osp; 1136 if (esp == iesp) 1137 goto bot; 1138 iesp = esp; 1139 goto up; 1140 case o_reschedule: 1141 store_state(iesp); 1142 goto res; 1143 case e_RemapColor: 1144 oe_remap: store_state(iesp); 1145 remap: if (iesp + 2 >= estop) { 1146 esp = iesp; 1147 code = ref_stack_extend(&e_stack, 2); 1148 if (code < 0) 1149 return_with_error_iref(code); 1150 iesp = esp; 1151 } 1152 packed_get(imemory, iref_packed, iesp + 1); 1153 make_oper(iesp + 2, 0, 1154 r_ptr(&istate->remap_color_info, 1155 int_remap_color_info_t)->proc); 1156 iesp += 2; 1157 goto up; 1158 } 1159 iosp = osp; 1160 iesp = esp; 1161 return_with_code_iref(); 1162 case plain_exec(t_name): 1163 INCR(exec_name); 1164 pvalue = IREF->value.pname->pvalue; 1165 if (!pv_valid(pvalue)) { 1166 uint nidx = names_index(int_nt, IREF); 1167 uint htemp; 1168 1169 INCR(find_name); 1170 if ((pvalue = dict_find_name_by_index_inline(nidx, htemp)) == 0) 1171 return_with_error_iref(e_undefined); 1172 } 1173 /* Dispatch on the type of the value. */ 1174 /* Again, we have to over-populate the switch. */ 1175 switch (r_type_xe(pvalue)) { 1176 cases_invalid(): 1177 return_with_error_iref(e_Fatal); 1178 cases_nox(): /* access errors */ 1179 return_with_error_iref(e_invalidaccess); 1180 cases_lit_1(): 1181 cases_lit_2(): 1182 cases_lit_3(): 1183 cases_lit_4(): 1184 cases_lit_5(): 1185 INCR(name_lit); 1186 /* Just push the value */ 1187 if (iosp >= ostop) 1188 return_with_stackoverflow(pvalue); 1189 ++iosp; 1190 ref_assign_inline(iosp, pvalue); 1191 next(); 1192 case exec(t_array): 1193 case exec(t_mixedarray): 1194 case exec(t_shortarray): 1195 INCR(name_proc); 1196 /* This is an executable procedure, execute it. */ 1197 goto prst; 1198 case plain_exec(tx_op_add): 1199 goto x_add; 1200 case plain_exec(tx_op_def): 1201 goto x_def; 1202 case plain_exec(tx_op_dup): 1203 goto x_dup; 1204 case plain_exec(tx_op_exch): 1205 goto x_exch; 1206 case plain_exec(tx_op_if): 1207 goto x_if; 1208 case plain_exec(tx_op_ifelse): 1209 goto x_ifelse; 1210 case plain_exec(tx_op_index): 1211 goto x_index; 1212 case plain_exec(tx_op_pop): 1213 goto x_pop; 1214 case plain_exec(tx_op_roll): 1215 goto x_roll; 1216 case plain_exec(tx_op_sub): 1217 goto x_sub; 1218 case plain_exec(t_null): 1219 goto bot; 1220 case plain_exec(t_oparray): 1221 INCR(name_oparray); 1222 pvalue = (const ref *)pvalue->value.const_refs; 1223 goto opst; 1224 case plain_exec(t_operator): 1225 INCR(name_operator); 1226 { /* Shortcut for operators. */ 1227 /* See above for the logic. */ 1228 if (--ticks_left <= 0) { /* The following doesn't work, */ 1229 /* and I can't figure out why. */ 1230 /****** goto sst; ******/ 1231 } 1232 esp = iesp; 1233 osp = iosp; 1234 switch (code = call_operator(real_opproc(pvalue), 1235 i_ctx_p) 1236 ) { 1237 case 0: /* normal case */ 1238 case 1: /* alternative success case */ 1239 iosp = osp; 1240 next(); 1241 case o_push_estack: 1242 store_state(iesp); 1243 goto opush; 1244 case o_pop_estack: 1245 goto opop; 1246 case o_reschedule: 1247 store_state(iesp); 1248 goto res; 1249 case e_RemapColor: 1250 goto oe_remap; 1251 } 1252 iosp = osp; 1253 iesp = esp; 1254 return_with_error(code, pvalue); 1255 } 1256 case plain_exec(t_name): 1257 case exec(t_file): 1258 case exec(t_string): 1259 default: 1260 /* Not a procedure, reinterpret it. */ 1261 store_state(iesp); 1262 icount = 0; 1263 SET_IREF(pvalue); 1264 goto top; 1265 } 1266 case exec(t_file): 1267 { /* Executable file. Read the next token and interpret it. */ 1268 stream *s; 1269 scanner_state sstate; 1270 1271 check_read_known_file(s, IREF, return_with_error_iref); 1272 rt: 1273 if (iosp >= ostop) /* check early */ 1274 return_with_stackoverflow_iref(); 1275 osp = iosp; /* scan_token uses ostack */ 1276 scanner_state_init_options(&sstate, i_ctx_p->scanner_options); 1277 again: 1278 code = scan_token(i_ctx_p, s, &token, &sstate); 1279 iosp = osp; /* ditto */ 1280 switch (code) { 1281 case 0: /* read a token */ 1282 /* It's worth checking for literals, which make up */ 1283 /* the majority of input tokens, before storing the */ 1284 /* state on the e-stack. Note that because of //, */ 1285 /* the token may have *any* type and attributes. */ 1286 /* Note also that executable arrays aren't executed */ 1287 /* at the top level -- they're treated as literals. */ 1288 if (!r_has_attr(&token, a_executable) || 1289 r_is_array(&token) 1290 ) { /* If scan_token used the o-stack, */ 1291 /* we know we can do a push now; if not, */ 1292 /* the pre-check is still valid. */ 1293 iosp++; 1294 ref_assign_inline(iosp, &token); 1295 goto rt; 1296 } 1297 store_state(iesp); 1298 /* Push the file on the e-stack */ 1299 if (iesp >= estop) 1300 return_with_error_iref(e_execstackoverflow); 1301 esfile_set_cache(++iesp); 1302 ref_assign_inline(iesp, IREF); 1303 SET_IREF(&token); 1304 icount = 0; 1305 goto top; 1306 case e_undefined: /* //name undefined */ 1307 return_with_error(code, &token); 1308 case scan_EOF: /* end of file */ 1309 esfile_clear_cache(); 1310 goto bot; 1311 case scan_BOS: 1312 /* Binary object sequences */ 1313 /* ARE executed at the top level. */ 1314 store_state(iesp); 1315 /* Push the file on the e-stack */ 1316 if (iesp >= estop) 1317 return_with_error_iref(e_execstackoverflow); 1318 esfile_set_cache(++iesp); 1319 ref_assign_inline(iesp, IREF); 1320 pvalue = &token; 1321 goto pr; 1322 case scan_Refill: 1323 store_state(iesp); 1324 /* iref may point into the exec stack; */ 1325 /* save its referent now. */ 1326 ref_assign_inline(&token, IREF); 1327 /* Push the file on the e-stack */ 1328 if (iesp >= estop) 1329 return_with_error_iref(e_execstackoverflow); 1330 ++iesp; 1331 ref_assign_inline(iesp, &token); 1332 esp = iesp; 1333 osp = iosp; 1334 code = scan_handle_refill(i_ctx_p, &token, &sstate, 1335 true, true, 1336 ztokenexec_continue); 1337 scan_cont: 1338 iosp = osp; 1339 iesp = esp; 1340 switch (code) { 1341 case 0: 1342 iesp--; /* don't push the file */ 1343 goto again; /* stacks are unchanged */ 1344 case o_push_estack: 1345 esfile_clear_cache(); 1346 if (--ticks_left > 0) 1347 goto up; 1348 goto slice; 1349 } 1350 /* must be an error */ 1351 iesp--; /* don't push the file */ 1352 return_with_code_iref(); 1353 case scan_Comment: 1354 case scan_DSC_Comment: { 1355 /* See scan_Refill above for comments. */ 1356 ref file_token; 1357 1358 store_state(iesp); 1359 ref_assign_inline(&file_token, IREF); 1360 if (iesp >= estop) 1361 return_with_error_iref(e_execstackoverflow); 1362 ++iesp; 1363 ref_assign_inline(iesp, &file_token); 1364 esp = iesp; 1365 osp = iosp; 1366 code = ztoken_handle_comment(i_ctx_p, &file_token, 1367 &sstate, &token, 1368 code, true, true, 1369 ztokenexec_continue); 1370 } 1371 goto scan_cont; 1372 default: /* error */ 1373 return_with_code_iref(); 1374 } 1375 } 1376 case exec(t_string): 1377 { /* Executable string. Read a token and interpret it. */ 1378 stream ss; 1379 scanner_state sstate; 1380 1381 scanner_state_init_options(&sstate, SCAN_FROM_STRING); 1382 s_init(&ss, NULL); 1383 sread_string(&ss, IREF->value.bytes, r_size(IREF)); 1384 osp = iosp; /* scan_token uses ostack */ 1385 code = scan_token(i_ctx_p, &ss, &token, &sstate); 1386 iosp = osp; /* ditto */ 1387 switch (code) { 1388 case 0: /* read a token */ 1389 case scan_BOS: /* binary object sequence */ 1390 store_state(iesp); 1391 /* If the updated string isn't empty, push it back */ 1392 /* on the e-stack. */ 1393 { 1394 uint size = sbufavailable(&ss); 1395 1396 if (size) { 1397 if (iesp >= estop) 1398 return_with_error_iref(e_execstackoverflow); 1399 ++iesp; 1400 iesp->tas.type_attrs = IREF->tas.type_attrs; 1401 iesp->value.const_bytes = sbufptr(&ss); 1402 r_set_size(iesp, size); 1403 } 1404 } 1405 if (code == 0) { 1406 SET_IREF(&token); 1407 icount = 0; 1408 goto top; 1409 } 1410 /* Handle BOS specially */ 1411 pvalue = &token; 1412 goto pr; 1413 case scan_EOF: /* end of string */ 1414 goto bot; 1415 case scan_Refill: /* error */ 1416 code = gs_note_error(e_syntaxerror); 1417 default: /* error */ 1418 return_with_code_iref(); 1419 } 1420 } 1421 /* Handle packed arrays here by re-dispatching. */ 1422 /* This also picks up some anomalous cases of non-packed arrays. */ 1423 default: 1424 { 1425 uint index; 1426 1427 switch (*iref_packed >> r_packed_type_shift) { 1428 case pt_full_ref: 1429 case pt_full_ref + 1: 1430 INCR(p_full); 1431 if (iosp >= ostop) 1432 return_with_stackoverflow_iref(); 1433 /* We know this can't be an executable object */ 1434 /* requiring special handling, so we just push it. */ 1435 ++iosp; 1436 /* We know that refs are properly aligned: */ 1437 /* see packed.h for details. */ 1438 ref_assign_inline(iosp, IREF); 1439 next(); 1440 case pt_executable_operator: 1441 index = *iref_packed & packed_value_mask; 1442 if (--ticks_left <= 0) { /* The following doesn't work, */ 1443 /* and I can't figure out why. */ 1444 /****** goto sst_short; ******/ 1445 } 1446 if (!op_index_is_operator(index)) { 1447 INCR(p_exec_oparray); 1448 store_state_short(iesp); 1449 /* Call the operator procedure. */ 1450 index -= op_def_count; 1451 pvalue = (const ref *) 1452 (index < r_size(&op_array_table_global.table) ? 1453 op_array_table_global.table.value.const_refs + 1454 index : 1455 op_array_table_local.table.value.const_refs + 1456 (index - r_size(&op_array_table_global.table))); 1457 goto oppr; 1458 } 1459 INCR(p_exec_operator); 1460 /* See the main plain_exec(t_operator) case */ 1461 /* for details of what happens here. */ 1462 #if PACKED_SPECIAL_OPS 1463 /* 1464 * We arranged in iinit.c that the special ops 1465 * have operator indices starting at 1. 1466 * 1467 * The (int) cast in the next line is required 1468 * because some compilers don't allow arithmetic 1469 * involving two different enumerated types. 1470 */ 1471 # define case_xop(xop) case xop - (int)tx_op + 1 1472 switch (index) { 1473 case_xop(tx_op_add):goto x_add; 1474 case_xop(tx_op_def):goto x_def; 1475 case_xop(tx_op_dup):goto x_dup; 1476 case_xop(tx_op_exch):goto x_exch; 1477 case_xop(tx_op_if):goto x_if; 1478 case_xop(tx_op_ifelse):goto x_ifelse; 1479 case_xop(tx_op_index):goto x_index; 1480 case_xop(tx_op_pop):goto x_pop; 1481 case_xop(tx_op_roll):goto x_roll; 1482 case_xop(tx_op_sub):goto x_sub; 1483 case 0: /* for dumb compilers */ 1484 default: 1485 ; 1486 } 1487 # undef case_xop 1488 #endif 1489 INCR(p_exec_non_x_operator); 1490 esp = iesp; 1491 osp = iosp; 1492 switch (code = call_operator(op_index_proc(index), i_ctx_p)) { 1493 case 0: 1494 case 1: 1495 iosp = osp; 1496 next_short(); 1497 case o_push_estack: 1498 store_state_short(iesp); 1499 goto opush; 1500 case o_pop_estack: 1501 iosp = osp; 1502 if (esp == iesp) { 1503 next_short(); 1504 } 1505 iesp = esp; 1506 goto up; 1507 case o_reschedule: 1508 store_state_short(iesp); 1509 goto res; 1510 case e_RemapColor: 1511 store_state_short(iesp); 1512 goto remap; 1513 } 1514 iosp = osp; 1515 iesp = esp; 1516 return_with_code_iref(); 1517 case pt_integer: 1518 INCR(p_integer); 1519 if (iosp >= ostop) 1520 return_with_stackoverflow_iref(); 1521 ++iosp; 1522 make_int(iosp, 1523 ((int)*iref_packed & packed_int_mask) + 1524 packed_min_intval); 1525 next_short(); 1526 case pt_literal_name: 1527 INCR(p_lit_name); 1528 { 1529 uint nidx = *iref_packed & packed_value_mask; 1530 1531 if (iosp >= ostop) 1532 return_with_stackoverflow_iref(); 1533 ++iosp; 1534 name_index_ref_inline(int_nt, nidx, iosp); 1535 next_short(); 1536 } 1537 case pt_executable_name: 1538 INCR(p_exec_name); 1539 { 1540 uint nidx = *iref_packed & packed_value_mask; 1541 1542 pvalue = name_index_ptr_inline(int_nt, nidx)->pvalue; 1543 if (!pv_valid(pvalue)) { 1544 uint htemp; 1545 1546 INCR(p_find_name); 1547 if ((pvalue = dict_find_name_by_index_inline(nidx, htemp)) == 0) { 1548 names_index_ref(int_nt, nidx, &token); 1549 return_with_error(e_undefined, &token); 1550 } 1551 } 1552 if (r_has_masked_attrs(pvalue, a_execute, a_execute + a_executable)) { /* Literal, push it. */ 1553 INCR(p_name_lit); 1554 if (iosp >= ostop) 1555 return_with_stackoverflow_iref(); 1556 ++iosp; 1557 ref_assign_inline(iosp, pvalue); 1558 next_short(); 1559 } 1560 if (r_is_proc(pvalue)) { /* This is an executable procedure, */ 1561 /* execute it. */ 1562 INCR(p_name_proc); 1563 store_state_short(iesp); 1564 goto pr; 1565 } 1566 /* Not a literal or procedure, reinterpret it. */ 1567 store_state_short(iesp); 1568 icount = 0; 1569 SET_IREF(pvalue); 1570 goto top; 1571 } 1572 /* default can't happen here */ 1573 } 1574 } 1575 } 1576 /* Literal type, just push it. */ 1577 if (iosp >= ostop) 1578 return_with_stackoverflow_iref(); 1579 ++iosp; 1580 ref_assign_inline(iosp, IREF); 1581 bot:next(); 1582 out: /* At most 1 more token in the current procedure. */ 1583 /* (We already decremented icount.) */ 1584 if (!icount) { 1585 /* Pop the execution stack for tail recursion. */ 1586 iesp--; 1587 iref_packed = IREF_NEXT(iref_packed); 1588 goto top; 1589 } 1590 up:if (--ticks_left < 0) 1591 goto slice; 1592 /* See if there is anything left on the execution stack. */ 1593 if (!r_is_proc(iesp)) { 1594 SET_IREF(iesp--); 1595 icount = 0; 1596 goto top; 1597 } 1598 SET_IREF(iesp->value.refs); /* next element of array */ 1599 icount = r_size(iesp) - 1; 1600 if (icount <= 0) { /* <= 1 more elements */ 1601 iesp--; /* pop, or tail recursion */ 1602 if (icount < 0) 1603 goto up; 1604 } 1605 goto top; 1606 res: 1607 /* Some operator has asked for context rescheduling. */ 1608 /* We've done a store_state. */ 1609 *pi_ctx_p = i_ctx_p; 1610 code = (*gs_interp_reschedule_proc)(pi_ctx_p); 1611 i_ctx_p = *pi_ctx_p; 1612 sched: /* We've just called a scheduling procedure. */ 1613 /* The interpreter state is in memory; iref is not current. */ 1614 if (code < 0) { 1615 set_error(code); 1616 /* 1617 * We need a real object to return as the error object. 1618 * (It only has to last long enough to store in 1619 * *perror_object.) 1620 */ 1621 make_null_proc(&ierror.full); 1622 SET_IREF(ierror.obj = &ierror.full); 1623 goto error_exit; 1624 } 1625 /* Reload state information from memory. */ 1626 iosp = osp; 1627 iesp = esp; 1628 goto up; 1629 #if 0 /****** ****** ***** */ 1630 sst: /* Time-slice, but push the current object first. */ 1631 store_state(iesp); 1632 if (iesp >= estop) 1633 return_with_error_iref(e_execstackoverflow); 1634 iesp++; 1635 ref_assign_inline(iesp, iref); 1636 #endif /****** ****** ***** */ 1637 slice: /* It's time to time-slice or garbage collect. */ 1638 /* iref is not live, so we don't need to do a store_state. */ 1639 osp = iosp; 1640 esp = iesp; 1641 /* If ticks_left <= -100, we need to GC now. */ 1642 if (ticks_left <= -100) { /* We need to garbage collect now. */ 1643 *pi_ctx_p = i_ctx_p; 1644 code = interp_reclaim(pi_ctx_p, -1); 1645 i_ctx_p = *pi_ctx_p; 1646 } else if (gs_interp_time_slice_proc) { 1647 *pi_ctx_p = i_ctx_p; 1648 code = (*gs_interp_time_slice_proc)(pi_ctx_p); 1649 i_ctx_p = *pi_ctx_p; 1650 } else 1651 code = 0; 1652 ticks_left = gs_interp_time_slice_ticks; 1653 set_code_on_interrupt(imemory, &code); 1654 goto sched; 1655 1656 /* Error exits. */ 1657 1658 rweci: 1659 ierror.code = code; 1660 rwei: 1661 ierror.obj = IREF; 1662 rwe: 1663 if (!r_is_packed(iref_packed)) 1664 store_state(iesp); 1665 else { 1666 /* 1667 * We need a real object to return as the error object. 1668 * (It only has to last long enough to store in *perror_object.) 1669 */ 1670 packed_get(imemory, (const ref_packed *)ierror.obj, &ierror.full); 1671 store_state_short(iesp); 1672 if (IREF == ierror.obj) 1673 SET_IREF(&ierror.full); 1674 ierror.obj = &ierror.full; 1675 } 1676 error_exit: 1677 if (ERROR_IS_INTERRUPT(ierror.code)) { /* We must push the current object being interpreted */ 1678 /* back on the e-stack so it will be re-executed. */ 1679 /* Currently, this is always an executable operator, */ 1680 /* but it might be something else someday if we check */ 1681 /* for interrupts in the interpreter loop itself. */ 1682 if (iesp >= estop) 1683 code = e_execstackoverflow; 1684 else { 1685 iesp++; 1686 ref_assign_inline(iesp, IREF); 1687 } 1688 } 1689 esp = iesp; 1690 osp = iosp; 1691 ref_assign_inline(perror_object, ierror.obj); 1692 return gs_log_error(ierror.code, __FILE__, ierror.line); 1693 } 1694 1695 /* Pop the bookkeeping information for a normal exit from a t_oparray. */ 1696 private int 1697 oparray_pop(i_ctx_t *i_ctx_p) 1698 { 1699 esp -= 3; 1700 return o_pop_estack; 1701 } 1702 1703 /* Restore the stack pointers after an error inside a t_oparray procedure. */ 1704 /* This procedure is called only from pop_estack. */ 1705 private int 1706 oparray_cleanup(i_ctx_t *i_ctx_p) 1707 { /* esp points just below the cleanup procedure. */ 1708 es_ptr ep = esp; 1709 uint ocount_old = (uint) ep[2].value.intval; 1710 uint dcount_old = (uint) ep[3].value.intval; 1711 uint ocount = ref_stack_count(&o_stack); 1712 uint dcount = ref_stack_count(&d_stack); 1713 1714 if (ocount > ocount_old) 1715 ref_stack_pop(&o_stack, ocount - ocount_old); 1716 if (dcount > dcount_old) { 1717 ref_stack_pop(&d_stack, dcount - dcount_old); 1718 dict_set_top(); 1719 } 1720 return 0; 1721 } 1722 1723 /* Don't restore the stack pointers. */ 1724 private int 1725 oparray_no_cleanup(i_ctx_t *i_ctx_p) 1726 { 1727 return 0; 1728 } 1729 1730 /* Find the innermost oparray. */ 1731 private ref * 1732 oparray_find(i_ctx_t *i_ctx_p) 1733 { 1734 long i; 1735 ref *ep; 1736 1737 for (i = 0; (ep = ref_stack_index(&e_stack, i)) != 0; ++i) { 1738 if (r_is_estack_mark(ep) && 1739 (ep->value.opproc == oparray_cleanup || 1740 ep->value.opproc == oparray_no_cleanup) 1741 ) 1742 return ep; 1743 } 1744 return 0; 1745 } 1746 1747 /* <bool> .setstackprotect - */ 1748 /* Set whether to protect the stack for the innermost oparray. */ 1749 private int 1750 zsetstackprotect(i_ctx_t *i_ctx_p) 1751 { 1752 os_ptr op = osp; 1753 ref *ep = oparray_find(i_ctx_p); 1754 1755 check_type(*op, t_boolean); 1756 if (ep == 0) 1757 return_error(e_rangecheck); 1758 ep->value.opproc = 1759 (op->value.boolval ? oparray_cleanup : oparray_no_cleanup); 1760 pop(1); 1761 return 0; 1762 } 1763 1764 /* - .currentstackprotect <bool> */ 1765 /* Return the stack protection status. */ 1766 private int 1767 zcurrentstackprotect(i_ctx_t *i_ctx_p) 1768 { 1769 os_ptr op = osp; 1770 ref *ep = oparray_find(i_ctx_p); 1771 1772 if (ep == 0) 1773 return_error(e_rangecheck); 1774 push(1); 1775 make_bool(op, ep->value.opproc == oparray_cleanup); 1776 return 0; 1777 } 1778