PostScript 内部错误处理程序的描述
Description of PostScript internal error handler procedures
不知道这个问题的标题应该怎么...
我正在研究解释器,目前正在研究错误处理。我看到有一个 $error 和 errordict 字典存储在 systemdict 中。
PLRM 包含有关可能发生错误的信息以及处理这些错误的几个步骤。但是,当我在 ghostscript 中执行此命令时:
errordict /Whosebug get ==
我收到此信息:
{/Whosebug {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 /Whosebug get type pstack
结果:
packedarraytype
现在在哪里可以找到此类信息(哪本手册?)?这些程序在哪里描述,以便我可以实施它们。
不仅仅是报错,其他算子好像也有一个packedarray(procedure)作为value,但是我在PLRM中找不到这个procedure的实现。
一旦你拿到书 Inside Postscript,这会变得更加清楚,但我可以总结一下。
仅从上面的转储很难看出,但是如果您以相同的方式转储多个错误处理程序,很明显中间的大过程主体对于所有处理程序都是相同的,并且所有处理程序都遵循将错误名称传递给此过程的相同模式(timeout
错误除外)。你实际上会像这样实现上面的内容:
errordict /stackunderflow {
/stackunderflow //signalerror exec
} put
其中 signalerror
实现了公共代码。对于 timeout
错误(如果你选择实现那个),没有 command 放在堆栈上,所以它的 errordict
程序略有不同.
errordict /timeout {
/timeout /timeout //signalerror exec
} bind put
signalerror
(或者.error
是书上描述的名字)对所有栈进行快照并保存在$error
字典中。
所以错误的顺序通常是:
- 错误是通过在
errordict
中查找错误名称并执行此过程来触发的。
errordict
过程调用 signalerror
,将错误名称传递给它。
signalerror
获取堆栈快照,将快照保存在 $error
中,然后调用 stop
.
stop
弹出 exec 堆栈,直到最近的封闭 stopped context 由 stopped
运算符建立。
- 如果程序没有建立自己的stopped context来捕获错误,它将被启动调用的外层
stopped { handleerror } if
捕获包含整个用户程序的代码。
handleerror
使用 $error
中的信息打印错误报告。
顺便说一句,您可以将 packedarray
实现为 只读 数组。在内存受限打印机的最早实现中需要它们,但我发现设计更紧凑的对象表示太复杂了。在行为上,与常规数组的唯一区别是打包数组必须 只读.
不知道这个问题的标题应该怎么...
我正在研究解释器,目前正在研究错误处理。我看到有一个 $error 和 errordict 字典存储在 systemdict 中。
PLRM 包含有关可能发生错误的信息以及处理这些错误的几个步骤。但是,当我在 ghostscript 中执行此命令时:
errordict /Whosebug get ==
我收到此信息:
{/Whosebug {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 /Whosebug get type pstack
结果:
packedarraytype
现在在哪里可以找到此类信息(哪本手册?)?这些程序在哪里描述,以便我可以实施它们。
不仅仅是报错,其他算子好像也有一个packedarray(procedure)作为value,但是我在PLRM中找不到这个procedure的实现。
一旦你拿到书 Inside Postscript,这会变得更加清楚,但我可以总结一下。
仅从上面的转储很难看出,但是如果您以相同的方式转储多个错误处理程序,很明显中间的大过程主体对于所有处理程序都是相同的,并且所有处理程序都遵循将错误名称传递给此过程的相同模式(timeout
错误除外)。你实际上会像这样实现上面的内容:
errordict /stackunderflow {
/stackunderflow //signalerror exec
} put
其中 signalerror
实现了公共代码。对于 timeout
错误(如果你选择实现那个),没有 command 放在堆栈上,所以它的 errordict
程序略有不同.
errordict /timeout {
/timeout /timeout //signalerror exec
} bind put
signalerror
(或者.error
是书上描述的名字)对所有栈进行快照并保存在$error
字典中。
所以错误的顺序通常是:
- 错误是通过在
errordict
中查找错误名称并执行此过程来触发的。 errordict
过程调用signalerror
,将错误名称传递给它。signalerror
获取堆栈快照,将快照保存在$error
中,然后调用stop
.stop
弹出 exec 堆栈,直到最近的封闭 stopped context 由stopped
运算符建立。- 如果程序没有建立自己的stopped context来捕获错误,它将被启动调用的外层
stopped { handleerror } if
捕获包含整个用户程序的代码。 handleerror
使用$error
中的信息打印错误报告。
顺便说一句,您可以将 packedarray
实现为 只读 数组。在内存受限打印机的最早实现中需要它们,但我发现设计更紧凑的对象表示太复杂了。在行为上,与常规数组的唯一区别是打包数组必须 只读.