[gs-cvs] rev 7439 - trunk/gs/src
lpd at ghostscript.com
lpd at ghostscript.com
Fri Dec 1 23:24:01 PST 2006
Author: lpd
Date: 2006-12-01 23:24:01 -0800 (Fri, 01 Dec 2006)
New Revision: 7439
Modified:
trunk/gs/src/isave.h
trunk/gs/src/zvmem.c
Log:
Fixes bug: save objects are simple in LL1 and LL2, but composite in LL3, so
restore must treat save objects on the stack differently depending on the
languagelevel. (PS3 CET 30-04-2, and some file in the PS2 tests, actually
care about this.)
Modified: trunk/gs/src/isave.h
===================================================================
--- trunk/gs/src/isave.h 2006-12-02 06:34:29 UTC (rev 7438)
+++ trunk/gs/src/isave.h 2006-12-02 07:24:01 UTC (rev 7439)
@@ -21,15 +21,20 @@
#include "idosave.h"
/*
- * According to the PostScript language definition, save objects are simple,
- * not composite. Consequently, we cannot use their natural representation,
- * namely a t_struct pointing to an alloc_save_t, since we aren't willing to
- * allocate them all in global VM and rely on garbage collection to clean
- * them up. Instead, we assign each one a unique "save ID", and store this
- * in the alloc_save_t object. Mapping the number to the object requires
- * at most searching the local save chain for the current gs_dual_memory_t,
- * and this approach means we don't have to do anything to invalidate
- * save objects when we do a restore.
+ * In PLRM2, save objects are simple, not composite. Consequently, we
+ * cannot use their natural representation, namely a t_struct pointing to an
+ * alloc_save_t, since we aren't willing to allocate them all in global VM
+ * and rely on garbage collection to clean them up. Instead, we assign each
+ * one a unique "save ID", and store this in the alloc_save_t object.
+ * Mapping the number to the object requires at most searching the local
+ * save chain for the current gs_dual_memory_t, and this approach means we
+ * don't have to do anything to invalidate save objects when we do a
+ * restore.
+ *
+ * In PLRM3, Adobe did the reasonable thing and changed save objects to
+ * composite. However, this means that 'restore' must treat save objects on
+ * the stack differently in LL2 vs. LL3 (yes, the Genoa LL2 and LL3 tests
+ * require this!). See zvmem.c:restore_check_stack.
*/
#ifndef alloc_save_t_DEFINED /* also in inamedef.h */
typedef struct alloc_save_s alloc_save_t;
Modified: trunk/gs/src/zvmem.c
===================================================================
--- trunk/gs/src/zvmem.c 2006-12-02 06:34:29 UTC (rev 7438)
+++ trunk/gs/src/zvmem.c 2006-12-02 07:24:01 UTC (rev 7439)
@@ -97,7 +97,7 @@
/* <save> restore - */
private int restore_check_operand(os_ptr, alloc_save_t **, gs_dual_memory_t *);
-private int restore_check_stack(const ref_stack_t *, const alloc_save_t *, bool);
+private int restore_check_stack(const i_ctx_t *i_ctx_p, const ref_stack_t *, const alloc_save_t *, bool);
private void restore_fix_stack(ref_stack_t *, const alloc_save_t *, bool);
int
zrestore(i_ctx_t *i_ctx_p)
@@ -120,9 +120,9 @@
{
int code;
- if ((code = restore_check_stack(&o_stack, asave, false)) < 0 ||
- (code = restore_check_stack(&e_stack, asave, true)) < 0 ||
- (code = restore_check_stack(&d_stack, asave, false)) < 0
+ if ((code = restore_check_stack(i_ctx_p, &o_stack, asave, false)) < 0 ||
+ (code = restore_check_stack(i_ctx_p, &e_stack, asave, true)) < 0 ||
+ (code = restore_check_stack(i_ctx_p, &d_stack, asave, false)) < 0
) {
osp++;
return code;
@@ -195,8 +195,8 @@
}
/* Check a stack to make sure all its elements are older than a save. */
private int
-restore_check_stack(const ref_stack_t * pstack, const alloc_save_t * asave,
- bool is_estack)
+restore_check_stack(const i_ctx_t *i_ctx_p, const ref_stack_t * pstack,
+ const alloc_save_t * asave, bool is_estack)
{
ref_stack_enum_t rsenum;
@@ -210,6 +210,14 @@
switch (r_type(stkp)) {
case t_array:
+ /*
+ * Zero-length arrays are a special case: see the
+ * t_*array case (label rr:) in igc.c:gc_trace.
+ */
+ if (r_size(stkp) == 0) {
+ /*stkp->value.refs = (void *)0;*/
+ continue;
+ }
ptr = stkp->value.refs;
break;
case t_dictionary:
@@ -246,6 +254,11 @@
break;
case t_mixedarray:
case t_shortarray:
+ /* See the t_array case above. */
+ if (r_size(stkp) == 0) {
+ /*stkp->value.packed = (void *)0;*/
+ continue;
+ }
ptr = stkp->value.packed;
break;
case t_device:
@@ -256,6 +269,20 @@
case t_astruct:
ptr = stkp->value.pstruct;
break;
+ case t_save:
+ /* See the comment in isave.h regarding the following. */
+ if (i_ctx_p->language_level <= 2)
+ continue;
+ ptr = alloc_find_save(&gs_imemory, stkp->value.saveid);
+ /*
+ * Invalid save objects aren't supposed to be possible
+ * in LL3, but just in case....
+ */
+ if (ptr == 0)
+ return_error(e_invalidrestore);
+ if (ptr == asave)
+ continue;
+ break;
default:
continue;
}
More information about the gs-cvs
mailing list