Description of PostScript internal error handler procedures

332 views Asked by At

I don't know how the title of this question should be...

I'm working on an interpreter, currently I was looking at error handling. I've seen that there is an $error and errordict dictionary which are stored in systemdict.

The PLRM contains information on which errors may occur and a few steps to handle them. However when I execute this command in ghostscript:

errordict /stackoverflow get ==

I receive this information:

{/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--}

And this seems to be a packedarray:

errordict /stackoverflow get type pstack

result:

packedarraytype

Now where do I find this kind of information (which manual?)? Where are these procedures described so that I can implement them.

It is not only for errors, but other operators also seem to have a packedarray (procedure) as the value, but I can't find the implementation of this procedures in the PLRM.

1

There are 1 answers

10
luser droog On BEST ANSWER

This will become more clear once you get the book Inside Postscript, but I can summarize somewhat.

It's hard to see just from the dump above, but if you dump several error handlers the same way, it would become obvious that the big procedure body in the middle is the same for all the handlers, and all handlers follow the same pattern of passing the error name to this procedure (with one exception for the timeout error). And you'd actually implement the above like this:

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

Where signalerror implements the common code. For the timeout error (if you choose to implement that one), there is no command to be placed on the stack, so its errordict procedure is slightly different.

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

signalerror (or .error is the name described in the book) takes snapshots of all the stacks and saves them in the $error dictionary.

So the sequence for an error is usually:

  1. error is triggered by looking up the error name in errordict and executing this procedure.
  2. the errordict procedure calls signalerror, passing it the error name.
  3. signalerror takes snapshots of the stacks, saving the snapshots in $error, and then calls stop.
  4. stop pops the exec stack until the nearest enclosing stopped context established by the stopped operator.
  5. if the program has not established its own stopped context to catch the error, it will be caught by an outer-level stopped { handleerror } if which was called by the startup code to bracket the whole user program.
  6. handleerror uses the information in $error to print an error report.

BTW, you can implement packedarray as read-only arrays. They were needed in the earliest implementations on memory-constrained printers, but I found it too complicated to design a more compact representation of objects. Behaviorally, the only difference from a regular array is that packed arrays must be read-only.