1

postscript 数组是否有最大大小

我写了一个 PS 文档,其中包含一个在 ghostview 中显示的数组,没有任何问题。

但是当这个数组中的项目数量增加时,ghostview 会引发以下异常:

ERROR: /stackoverflow in -file-
Operand stack:
   --nostringval--
Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   --nostringval--   --nostringval--   false   1   %stopped_push   1   3   %oparray_pop   1   3   %oparray_pop   1   3   %oparray_pop   1   3   %oparray_pop   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push
Dictionary stack:
   --dict:1122/1686(ro)(G)--   --dict:0/20(G)--   --dict:122/200(L)--
Current allocation mode is local
Last OS error: 2
Current file position is 301163
ESP Ghostscript 815.02: Unrecoverable error, exit code 1
4

1 回答 1

3

有一个最大数组长度:65535。这也是最大字符串长度。但这似乎不是这里的问题。

Postscript Level 2 取消了堆栈大小的限制,因此它应该自动扩展到虚拟内存系统可以管理的任何大小。如果您收到 /stackoverflow 错误;您需要将您的解释器至少升级到 Level 2 (1991) 标准。

编辑:也就是说,如果升级不是一种选择,有办法解决这个问题。

最有可能发生限制是因为堆栈是静态分配的。如果您可以访问源代码,您可以简单地增加大小并重新编译解释器。PLRM 1ed 中引用的限制是 500。

另一种选择是改变你使用堆栈的方式(更难)。如果您不能使用构造一个 1000 元素的数组,[]或者{}您仍然可以分配数组 ( 1000 array) 并用正常构造的切片 () 填充它dup dup 0 [ 0 1 .. 450 ] putinterval dup dup 450 [ 451 452 .. 900 ] putinterval dup dup 900 [ 901 902 .. 999 ] putinterval。请记住,标记也会占用堆栈上的空间;并且某些运算符实际上是过程,它们将需要堆栈空间来操作。

编辑:如果数组真的很大,数组切片可能会让你遇到总内存限制;因为如果你没有不断增长的堆栈,你可能也没有垃圾收集。上述方法留下了 1000 个数组元素在 VM 中使用和不可访问。使用packedarray切片可能会在某种程度上解决这个问题。

下一步是编写一个像 putinterval 和 packedarray 混合一样工作的过程,它可以将数据加载到一个数组中而无需创建临时数组。这可能会运行得更慢,因为我们正在更高级别重新实现低级别功能。

这是第一次刺。它预先读取(使用currentfile token)并将每个元素放入数组的后续位置。arrayfill必须是源行上的最后一个单词(如image),因此 currentfile 可以找到第一个元素(源行的其余部分在内部扫描仪缓冲区中)。

% array index count  arrayfill(NL)  array
% elem_0 elem_1 ..
% elem_count-1
/arrayfill { %a i c
    1 index add 1 sub %a ini fin
    1 exch { %a i
        2 copy %a i a i
        currentfile token pop %a i a i el
        put %a i
        pop %a
    } for
} def

%example
5 array 0 5 arrayfill
(0) (1) (2) (3) (4)
{=} forall
于 2011-09-29T14:21:45.767 回答