我正在尝试修复我的postscript解释器中的错误处理,并且当其中一个堆栈已满时,我很难想出处理程序执行的方法。
我正在使用的postscript级处理程序程序是Frank Merritt Braswell描述的“标准”程序, Inside Postscript。
/.error {
//$error exch /errorname exch put
//$error exch /command exch put
//$error /newerror true put
//$error /errorname get /VMerror ne {
//$error /ostackarray get null eq {
//$error /estackarray 250 array put
//$error /ostackarray 6000 array put
//$error /dstackarray 30 array put
} if
count
//$error /ostackarray get exch 0 exch getinterval astore
//$error exch /ostack exch put
//$error /dstack //$error /dstackarray get dictstack put
//$error /estack //$error /estackarray get execstack
dup length 2 sub 0 exch getinterval put
//$error /ostack get aload pop
} if
//$error /initializing get {
handleerror
} if
interrupt
} def
因此它需要操作数堆栈上的空间(对于$ error字典和名称和东西)和执行堆栈(对于过程体,如果执行)。因此,如果任何一个堆栈溢出,这个空间应该来自哪里?
我首先尝试解决execstackoverflow,因为使用execstack的操作数少于使用操作数堆栈。我定义了一个“缓冲区”大小
#define ERRDEPTH 5 /*space reserved on execstack for error handling*/
所有“exec”操作符函数都添加到空格检查中。例如。这是exec
运算符。
void Aexec(state *st, object x) { (void)st;
if ((tes-es)+1+ERRDEPTH >= ESSIZE) error(st,execstackoverflow);
pushe(x);
}
然后解释器循环检查更小的大小(因此在尝试运行处理程序时不会触发更多错误)。
bool eval (state *st) {
...
/* room to work? */
if ((tes-es) + 2 /*+ ERRDEPTH*/ > ESSIZE) error(st,execstackoverflow);
...
但它不起作用(SEGFAULT),除非我在C级错误处理程序中清空一些空格,就在它在execstack上推送(调度)PS处理程序之前。
...
if (e == execstackoverflow) { /* make some room! */
(void)pope(); (void)pope(); (void)pope(); (void)pope(); (void)pope();
(void)pope(); (void)pope(); (void)pope(); (void)pope(); (void)pope();
}
...
但现在我把婴儿扔出洗澡水了!堆栈顶部的那些条目可能只是修复错误的关键信息,我只是将它们扔进了深渊。
有人能提出更好的解决方法吗?
答案 0 :(得分:1)
在不了解您的代码的情况下,我会想象创建一个可以扩展自身的错误堆栈就是解决方案。