[gs-code-review] CET 20-02-02, don't restore the argument of operator begin

Alex Cherepanov alexcher at quadnet.net
Thu Apr 5 16:36:39 PDT 2007


Following Adobe implementation don't restore the operand of --begin--
when it overflows the dictionary stack. Fix CET 20-02-02.

DETAILS:
Implement the approach suggested by L. Peter Deutsch.

- Change the check_dstack macro in dstack.h so it works the same as
   check_estack in estack.h -- i.e., if the current dstack block is full,
   call ref_stack_extend and then only return an error if
   ref_stack_extend fails.
- Change the handling of e_dictstackoverflow in interp.c so it works
   the same as e_execstackoverflow -- i.e., it doesn't try to extend the
   stack.
- Change the implementation of zbegin in zdict.c to work like
   check_dstack. I.e., if the current dstack block is full, call
   ref_stack_extend; if ref_stack_extend returns e_dictstackoverflow, pop
   the operand from the ostack before returning the error code.

With this approach, the interpreter does not have to know anything about
special handling of dictstackoverflow, and the right thing happens in
the special case of the 'begin' operator.

DIFFERENCES:
No other CET or Comparefiles differences.

-------------- next part --------------
Index: gs/src/dstack.h
===================================================================
--- gs/src/dstack.h	(revision 7816)
+++ gs/src/dstack.h	(working copy)
@@ -46,7 +46,9 @@
 /* Macro to ensure enough room on the dictionary stack */
 #define check_dstack(n)\
   if ( dstop - dsp < (n) )\
-    { d_stack.requested = (n); return_error(e_dictstackoverflow); }
+    { int ds_code_ = ref_stack_extend(&d_stack, n);\
+      if ( ds_code_ < 0 ) return ds_code_;\
+    }
 
 /*
  * The dictionary stack is implemented as a linked list of blocks;
Index: gs/src/interp.c
===================================================================
--- gs/src/interp.c	(revision 7816)
+++ gs/src/interp.c	(working copy)
@@ -539,12 +539,10 @@
     /* we might be able to recover by adding or removing a block. */
     switch (code) {
 	case e_dictstackoverflow:
-	    if (ref_stack_extend(&d_stack, d_stack.requested) >= 0) {
-		dict_set_top();
-		doref = *perror_object;
-		epref = &doref;
-		goto again;
-	    }
+	    /* We don't have to handle this specially: */
+	    /* The only places that could generate it */
+	    /* use check_dstack, which does a ref_stack_extend, */
+	    /* so if` we get this error, it's a real one. */
 	    if (osp >= ostop) {
 		if ((ccode = ref_stack_extend(&o_stack, 1)) < 0)
 		    return ccode;
Index: gs/src/zdict.c
===================================================================
--- gs/src/zdict.c	(revision 7816)
+++ gs/src/zdict.c	(working copy)
@@ -59,8 +59,17 @@
 
     check_type(*op, t_dictionary);
     check_dict_read(*op);
-    if (dsp == dstop)
-	return_error(e_dictstackoverflow);
+    if ( dsp == dstop ) { 
+        int code = ref_stack_extend(&d_stack, 1);
+        if ( code < 0 ) {
+            if (code == e_dictstackoverflow) {
+                /* Adobe doesn't restore the operand that caused stack */
+                /* overflow. We do the same to match CET 20-02-02      */
+                pop(1);
+            }
+            return code;
+        }
+    }
     ++dsp;
     ref_assign(dsp, op);
     dict_set_top();


More information about the gs-code-review mailing list