Open ruv opened 6 years ago
Can you be more specific? What kind of hardware exceptions are you talking about and in what context? x86_64 in ring 0?
I mean exceptions in the user space, for example — integer division by zero, memory access violation, etc.
By handling I mean that CATCH
can catch such exceptions.
Gforth does. It catches some UNIX signals and turns them into exceptions. See the manual and engine/signals.c.
Yes, Gforth does it — in the version for Linux at least. But seemingly it doesn't work in the version for Windows.
Hope we will get all such Forth-systems to compose the list.
Pretty much every Forth system I have ever done - Forthmacs, Sun Forth, CForth, Open Firmware - has been able to handle hardware exceptions. In some cases, the complete state can be made visible so it is possible to inspect it from Forth, modify things like register values, and then resume from the saved/modified state - so Forth can debug its own assembly language. In other cases, the best you can do is return to Forth.
The complete capability can be very difficult to implement under operating systems, which rarely provide a documented (or stable across versions) way to get at the saved state vector. With great effort, I have succeeded in some cases, but it tends to be fragile and difficult to maintain. On a bare machine, where Forth is the operating system, it is much easier, since the exception state is documented as part of the instruction set architecture.
In CForth 123 0 ' / catch .
and 0 ' @ catch .
don't print ior number. Apparently, CForth doesn't transform hardware exception into Forth's THROW
— see signal_handler in main.c.
I'm not convinced that making hardware exceptions do a THROW is the right thing. It opens up the possibility of THROW from code that does not explicitly contain instances of THROW, ABORT, or ABORT" .
I am aware that some people disagree, and I know of Forth systems that do fold hardware exceptions into the CATCH / THROW framework.
In the specific case of divide-by-zero, it would be easy enough to add an explicit check for zero divisor in the division words, with gotos to the throw code. Other exceptions would require moving the sigsetjmp() from main() (which is used in OS-hosted CForth builds, but often omitted in standalone/bare-metal/embedded builds) into forth.c, thus adding a system library dependency. If you wish to try that change, I will consider a patch.
On Sun, Feb 04, 2018 at 03:51:09AM +0000, Mitch Bradley wrote:
I'm not convinced that making hardware exceptions do a THROW is the right thing. It opens up the possibility of THROW from code that does not explicitly contain instances of THROW, ABORT, or ABORT" .
Yes. And the problem is?
There were some languages that required declaring all exceptions that could be thrown, but even my collegue who is very much into static checking does not think that is a good idea. E.g., Java has both checked exceptions that need to be declared, and unchecked exceptions that do not need to be declared, so Java code may get an exception that is not declared (and the throw is not visible to the code that receives it, given that Java has separate compilation).
And standard Forth has throw codes for stuff like "Invalid memory access" and "Address alignment exception", and "User Interrupt" which are perfect for events without explicit THROW.
In the specific case of divide-by-zero, it would be easy enough to add an explicit check for zero divisor in the division words, with gotos to the throw code.
That's appropriate when the hardware does not check it. But when the hardware does, why add this overhead?
More precise, the fist question is which the open source 64bit Forth-systems can handle hardware exceptions?