[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: embedding mzscheme into a C++ application
Quoting Chris Uzdavinis:
> > One possibility is to diallow the jump.
>
> What consequences follow when this route is taken? (Other than not
> being able to jump?)
Probably the only notable consequence is that exception handling will
not work the way the Scheme programmer expects: the exception is
silently "handled" at the point where the jump is blocked.
> > If so, couldn't you catch the longjmp at the C++->Scheme boundary,
> > raise a C++ exception, catch the exception at the Scheme->C++ entry
> > point, and longjmp again?
>
> I think that would work. But there is an uncertainty of what the
> stack variables values are when the longjmp is "caught". Do they
> revert to the value they had at the time setjmp was called, or do they
> retain their value from when they called into the next function (which
> eventually lead up to the longjmp)? We need to make sure that the
> values are not rolled back, so additionally, we must declare all the
> stack-based objects as being "volatile."
I'm not sure what you mean. I imagine that the `setjmp' appears just
before the call into Scheme, and you'll only need `volatile' on local
variables in that function using `setjmp'. The other stack variables
will be fine.
> One final question on this issue then: if I want to implement your
> suggestion, by re-longjmp-ing at the end of my C++ function, how do I
> know which jump-buffer to longjmp into? (I'm not terribly familiar
> with longjmp, as it's fairly strongly discouraged in C++.) Is there a
> way to ask for the "next higher" jump buffer... which is where the
> jump would have gone had I not intercepted it?
Before using `setjmp' on `scheme_error_buf' to catch jumps, save the
content of `scheme_error_buf'. Copy the content back after catching a
jump or after a normal return. Something like this:
mz_jmp_buf save;
memcpy(&save, &scheme_error_buf, sizeof(mz_jmp_buf));
if (scheme_setjmp(scheme_error_buf)) {
/* jump */
memcpy(&scheme_error_buf, &save, sizeof(mz_jmp_buf));
... raise a C++ exception ...
} else {
scheme_eval_string("x", scheme_env); /* or some other scheme_ call */
}
memcpy(&scheme_error_buf, &save, sizeof(mz_jmp_buf));
/* Normal return... */
Then, when you catch the C++ exception at the the Scheme->C++ boundary,
use `scheme_longjmp(scheme_error_buf, 1)'.
Matthew