【问题标题】:Description of PostScript internal error handler proceduresPostScript 内部错误处理程序的描述
【发布时间】:2015-06-09 10:13:37
【问题描述】:

我不知道这个问题的标题应该怎么写……

我正在研究解释器,目前我正在研究错误处理。我看到有一个 $error 和 errordict 字典存储在 systemdict 中。

PLRM 包含有关可能发生的错误以及处理这些错误的几个步骤的信息。但是,当我在 ghostscript 中执行此命令时:

errordict /stackoverflow get ==

我收到以下信息:

{/stackoverflow {1 --.instopped-- {null --eq-- {--pop-- --pop-- --stop--} --if--} --if-- (I) false --.setdebug-- $error /.inerror --get-- 1 --.instopped-- {--pop-- } {--pop-- true} --ifelse-- {.unstoppederrorhandler} --if-- $error /globalmode --.currentglobal-- false --.setglobal-- --put-- $error /.inerror true --put-- $error /newerror true --put-- $error --exch-- /errorname --exch-- --put-- $error --exch-- /command --exch-- --put-- $error /errorinfo --known-- --not-- {$error /errorinfo null --put--} --if-- $error /recordstacks --get-- $error /errorname --get-- /VMerror --ne-- --and -- {--count-- --array-- --astore-- --dup-- $error /ostack 4 -1 --roll-- --countexecstack-- --array-- --execstack-- --dup-- --length-- 2 --sub-- 0 --exch-- --getinterval-- $error /estack 3 -1 --roll-- --countdictstack-- --array-- -dictstack-- $error /dstack 3 -1 --roll-- --put-- --put-- --put-- --aload-- --pop--} {$error /dstack --. undef-- $error /estack --.undef-- $error /ostack --.undef--} --ifelse-- $error /position --currentfile-- --status-- {--currentfile-- { --fileposition--} .internalstopped {--pop-- null} --if--} {$error /command --get-- --dup-- --type-- /filetype --eq-- {{--fileposition--} .internalstopped {--pop-- null } --if--} {--pop-- null} --ifelse--} --ifelse-- --put-- $error /globalmode --get-- $error /.nosetlocal --get-- --and-- --.setglobal-- $error /.inerror false --put-- --stop--} --exec--}

这似乎是一个打包数组:

errordict /stackoverflow get type pstack

结果:

打包数组类型

现在我在哪里可以找到此类信息(哪个手册?)?这些过程在哪里描述,以便我可以实施它们。

不仅是报错,其他算子好像也有一个packedarray(procedure)作为值,但是我在PLRM中找不到这个procedure的实现。

【问题讨论】:

    标签: postscript


    【解决方案1】:

    一旦你拿到这本书Inside Postscript,这会变得更清楚,但我可以稍微总结一下。

    仅从上面的转储中很难看出,但是如果您以相同的方式转储多个错误处理程序,则很明显,中间的大过程体对于所有处理程序都是相同的,并且所有处理程序都遵循相同的将错误名称传递给此过程的模式(timeout 错误有一个例外)。你实际上会像这样实现上面的:

    errordict /stackunderflow {
        /stackunderflow //signalerror exec
    } put
    

    signalerror 实现了通用代码。对于timeout 错误(如果您选择实现该错误),没有command 可放置在堆栈上,因此其errordict 过程略有不同。

    errordict /timeout {
        /timeout /timeout //signalerror exec
    } bind put
    

    signalerror(或.error 是书中描述的名称)拍摄所有堆栈的快照并将它们保存在$error 字典中。

    所以错误的顺序通常是:

    1. 通过在errordict 中查找错误名称并执行此过程来触发错误。
    2. errordict 过程调用signalerror,将错误名称传递给它。
    3. signalerror 拍摄堆栈的快照,将快照保存在$error,然后调用stop
    4. stop 弹出 exec 堆栈,直到由 stopped 运算符建立的最近的封闭 已停止上下文
    5. 如果程序没有建立自己的已停止上下文来捕获错误,它将被启动代码调用的外层stopped { handleerror } if 捕获以括住整个用户程序.
    6. handleerror 使用 $error 中的信息打印错误报告。

    顺便说一句,您可以将packedarray 实现为只读 数组。在内存受限的打印机上的最早实现中需要它们,但我发现设计更紧凑的对象表示太复杂了。在行为上,与常规数组的唯一区别是打包数组必须是只读

    【讨论】:

    • 只是附带说明,Ghostscript 作为源提供,包括其所有 PostScript 机制。如果你真的想知道 GS 在做什么,你最好阅读源 PostScript(其中一些甚至有 cmets),而不是试图通过直接戳解释器来弄清楚发生了什么。但请记住,解决问题的方法不止一种,GS 不是明确的参考。
    • 我正在尝试尽可能地遵循 PLRM,但并未描述所有内容(例如 signalerror 在哪里?)我只尝试使用 GhostScript 来验证我的结果,如果它具有相同的输出。
    • 我不是。技术方面,我还停留在 80 年代。
    • @juFo 正如 Ken 所说,您可以查看 gs 源代码。看起来大部分错误处理都是here。或者你可以看看my interpreter
    • 我写过更多关于Error Handling here的文章
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    • 2012-01-07
    • 2012-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多