Search code examples
stackstack-overflowpostscript

postscript stack overflow differing on mac and linux and effected by font setting


To explain my question I will first provide some code and explain what it does:

% 1 1 65532{}for    % cut off on mac with font set
% 1 1 99996{}for    % cut off on mac without font set
% 1 1 300048{}for   % cut off on linux with font set
% 1 1 300368{}for   % cut off on linux without font set

% /Times-Roman findfont 10 scalefont setfont
showpage

When I un-comment lines 1 and 6 and run this postscript program on my mac I get a stack overflow however I don't get a stack overflow if I replace 65532 with any smaller integer. If I instead un-comment line 2 then again I have a stack overflow but not if I replace 99996 with any smaller integer. lines 3 and 4 are similar except on linux.

From this I have concluded the following: the postscript stack mac has length 99998 (3 numbers before the for loop and 99996 numbers created by the for loop gives 99999 numbers but this is one too many so the stack should be 99998 long). Similarly I have concluded that the linux stack is 300370 long. Let me know if any of this reasoning is incorrect. Also, why are they different?

Next, I have concluded that setting the font takes up 34464 items on the stack on mac but only 320 items on linux. Again, let me know if any of this seems incorrect.

First, it seems odd to me that setting the font should take up this much space at all, second why do they differ so much on mac and linux (over 100 times more space on mac)?

Finally, I'd like to know if there are any other operations in postscript that use up a large amount of space on the stack other than operations defined by the programmer. I'd consider a large amount to be greater than 100 items on the stack.

Thanks


Solution

  • A good place to learn more about this area is the PLRM appendix on Implementation Limits. Typical size of the operand stack in Level 1 was around 1000. In Level 2 (and beyond) the stack will grow to accommodate new objects but Postscript is not really suited to having so many objects on the stack.

    Fonts are implemented as dictionary objects, so they do not take up space on the stack but they do consume memory in the PostScript Virtual Memory. On the stack itself it only takes up space for 1 object.

    There are a handful of operators which can add many objects to the stack. Any kind of loop (like for which you've already discovered) can add objects to the stack. aload is another one since it spills the contents of an array on the stack.

    Practically, the stack size limitation shouldn't be a problem. If you have lots of data, then it really ought to be stored in data structures like arrays, strings, and dictionaries. Most situations where you may be tempted to put large amounts of data on the stack can be rewritten to be less stack-heavy.

    A large part of the design of PostScript is to make it very lightweight in memory usage for the the tasks it is good for. For example, the image operator in Level 1 takes a data-acquisition procedure rather than an array or string. The usual way to use this is to have the procedure read ahead in the source file to find its samples. A large image can be displayed without having to store all the samples in memory all at once. The data-acquisition procedure can use a small string buffer to read samples and return them piece by piece.