At Wed, 26 Jul 2017 14:44:05 -0700 (PDT), Thomas Dickerson wrote:
> Looking at this code specifically:
> 
> |  mz_jmp_buf * volatile save, fresh;
> |  save = scheme_current_thread->error_buf;
> |  scheme_current_thread->error_buf = &fresh;
> |
> |  if (scheme_setjmp(scheme_error_buf)) {
> |    /* There was an error or continuation invocation */
> |    if (scheme_jumping_to_continuation) {
> |      /* It was a continuation jump */
> |      scheme_longjmp(*save, 1);
> |
> |      /* To block the jump, instead: scheme_clear_escape(); */
> |    } else {
> |      /* It was a primitive error escape */
> |    }
> |  } else {
> |    scheme_eval_string("x", scheme_env);
> |  }
> |  scheme_current_thread->error_buf = save;
> 
> I have questions about a few things:
> (a) Why does the example check for an error *before* calling 
> `scheme_eval_string`, rather than afterward? Is this just something weird 
> with 
> setjmp/longjmp?

Yes, that's how setjmp() and longjmp() work. The initial call to
setjmp() always returns 0, etc.

> (b) How do I handle the "primitive error escape" branch, assuming I
> want to print a useful error message, and continue executing
> gracefully? It looks like `scheme_clear_escape` may be useful for
> preventing the exception from propagating, but I'm not sure about
> that from the documentation (or how I'd be able to capture the error
> message from the exception).

That branch corresponds to `abort-current-continuation`. If it's due to
an exception, then the exception was already printed and (probably) the
default error escape handler called `abort-current-continuation`.

Catching the value raised as an exception is not practical to do in C.
It's better to wrap up the work like `scheme_eval_string("x",
scheme_env)` in a thunk and call a Racket-implemented wrapper. Section
9.1 in "Inside Racket" shows one way to do that.

> (c) Is this style of error handling only necessary around blocks that
> are evaluating actual Racket code (via, e.g., `scheme_eval_string` or
> `scheme_dynamic_require`)? What about the
> `scheme_register_embedded_load` and `scheme_embedded_load` pair at
> the bottom of `declare_modules`? I ran my binary through the Unix
> `strings` command and the embedded data looks an awful lot like
> expanded S-expressions in plain text. Additionally, at what level of
> granularity should I structure the error handling? Does it need to be
> for *every* evaluation, individually? Or could I surround a whole
> block of evaluations with the same error handling code?

Declaring (as opposed to instantiating) a compiled module will normally
not raise an exception. Probably it's possible to construct a set of
embedded modules where there will be a declare-time error due to
conflicting or missing declarations, but I don't see how to make that
happen only sometimes.

The escape-catching pattern is needed anywhere that you don't want to
just exit/crash.

You can certainly call multiple `scheme_...` functions within a single
escape-handling block, including multiple calls to `scheme_eval_string`.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to