c - 如何处理计算器溢出?

标签 c error-handling stack-overflow interpreter postscript

我正在尝试修复我的 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();
    }
...

但现在我把婴儿连同洗澡水一起倒掉了!堆栈顶部的那些条目可能只是修复错误的关键信息,我只是把它们扔进了深渊。

谁能提出更好的解决方法?

最佳答案

在不太了解您的代码的情况下,我认为创建一个可以自行扩展的错误堆栈将是解决方案。

关于c - 如何处理计算器溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7976029/

相关文章:

iOS Facebook 网络共享 api - 如何判断用户是否点击了跳过

c - 指向char的指针数组和指向int的指针数组之间的区别

powershell - PowerShell高级功能中的错误处理

c - 返回字符串的子串

php - Laravel 3、mysql 或 redis down 显示空白屏幕而不是重定向到 500 错误屏幕

c - Aleph one 的 shell 代码在哪里 self 改变?

Haskell - 递归堆栈

android - 自定义 session 另一个类

c - 我怎样才能按字母顺序排列这个链表?

c - Linux,C 将 cat 与 exec(3) 结合使用