[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