Front page | perl.perl6.internals |
Postings from March 2006
[svn:parrot-pdd] r11993 - in trunk: . docs/pdds/clip
From:
allison
Date:
March 22, 2006 18:00
Subject:
[svn:parrot-pdd] r11993 - in trunk: . docs/pdds/clip
Message ID:
20060323020037.CD0B4CBA82@x12.develooper.com
Author: allison
Date: Wed Mar 22 18:00:36 2006
New Revision: 11993
Added:
trunk/docs/pdds/clip/pddXX_exceptions.pod
Changes in other areas also in this revision:
Modified:
trunk/ (props changed)
trunk/MANIFEST
Log:
A first draft of the PDD on exceptions.
Added: trunk/docs/pdds/clip/pddXX_exceptions.pod
==============================================================================
--- (empty file)
+++ trunk/docs/pdds/clip/pddXX_exceptions.pod Wed Mar 22 18:00:36 2006
@@ -0,0 +1,332 @@
+# Copyright: 2001-2006 The Perl Foundation.
+# $Id: $
+
+=head1 NAME
+
+docs/pdds/clip/pddXX_exceptions.pod - Parrot Exceptions
+
+=head1 ABSTRACT
+
+This document defines the requirements and implementation strategy for
+Parrot's exception system.
+
+=head1 VERSION
+
+$Revision: $
+
+=head1 DESCRIPTION
+
+An exception system gives user-developed code control over how run-time
+error conditions are handled. Exceptions are errors or unusual
+conditions that requires special processing. An exception handler
+performs the necessary steps to appropriately respond to a particular
+kind of exception.
+
+=head2 Exception Opcodes
+
+These are the opcodes relevant to exceptions and exception handlers:
+
+=over
+
+=item *
+
+C<push_eh> creates an exception handler and pushes it onto the control
+stack. It takes a label (the location of the exception handler) as its
+only argument. [Is this right? Treating exception handlers as label
+jumps rather than full subroutines seems error-prone.]
+
+=item *
+
+C<clear_eh> removes the most recently added exception from the control
+stack.
+
+=item *
+
+C<throw> throws an exception object.
+
+=item *
+
+C<rethrow> rethrows an exception object. It can only be called from
+inside an exception handler.
+
+=item *
+
+C<die> throws an exception. It takes two arguments, one for the severity
+of the exception and one for the type of exception.
+
+If the severity is C<EXCEPT_DOOMED>, it exits via a call to
+C<_exit($2)>, which is not a catchable exception.
+
+These are the constants defined for severity:
+
+ 0 EXCEPT_NORMAL
+ 1 EXCEPT_WARNING
+ 2 EXCEPT_ERROR
+ 3 EXCEPT_SEVERE
+ 4 EXCEPT_FATAL
+ 5 EXCEPT_DOOMED
+ 6 EXCEPT_EXIT
+
+These are the constants defined for exception types:
+
+ 0 E_Exception
+ 1 E_SystemExit
+ 2 E_StopIteration
+ 3 E_StandardError
+ 4 E_KeyboardInterrupt
+ 5 E_ImportError
+ 6 E_EnvironmentError
+ 7 E_IOError
+ 8 E_OSError
+ 9 E_WindowsError
+ 10 E_VMSError
+ 11 E_EOFError
+ 12 E_RuntimeError
+ 13 E_NotImplementedError
+ 14 E_LibraryNotLoadedError
+ 15 E_NameError
+ 16 E_UnboundLocalError
+ 17 E_AttributeError
+ 18 E_SyntaxError
+ 19 E_IndentationError
+ 20 E_TabError
+ 21 E_TypeError
+ 22 E_AssertionError
+ 23 E_LookupError
+ 24 E_IndexError
+ 25 E_KeyError
+ 26 E_ArithmeticError
+ 27 E_OverflowError
+ 28 E_ZeroDivisionError
+ 29 E_FloatingPointError
+ 30 E_ValueError
+ 31 E_UnicodeError
+ 32 E_UnicodeEncodeError
+ 33 E_UnicodeDecodeError
+ 34 E_UnicodeTranslateError
+ 35 E_ReferenceError
+ 36 E_SystemError
+ 37 E_MemoryError
+ 37 E_LAST_PYTHON_E
+ 38 BAD_BUFFER_SIZE
+ 39 MISSING_ENCODING_NAME
+ 40 INVALID_STRING_REPRESENTATION
+ 41 ICU_ERROR
+ 42 UNIMPLEMENTED
+ 43 NULL_REG_ACCESS
+ 44 NO_REG_FRAMES
+ 45 SUBSTR_OUT_OF_STRING
+ 46 ORD_OUT_OF_STRING
+ 47 MALFORMED_UTF8
+ 48 MALFORMED_UTF16
+ 49 MALFORMED_UTF32
+ 50 INVALID_CHARACTER
+ 51 INVALID_CHARTYPE
+ 52 INVALID_ENCODING
+ 53 INVALID_CHARCLASS
+ 54 NEG_REPEAT
+ 55 NEG_SUBSTR
+ 56 NEG_SLEEP
+ 57 NEG_CHOP
+ 58 INVALID_OPERATION
+ 59 ARG_OP_NOT_HANDLED
+ 60 KEY_NOT_FOUND
+ 61 JIT_UNAVAILABLE
+ 62 EXEC_UNAVAILABLE
+ 63 INTERP_ERROR
+ 64 PREDEREF_LOAD_ERROR
+ 65 PARROT_USAGE_ERROR
+ 66 PIO_ERROR
+ 67 PARROT_POINTER_ERROR
+ 68 DIV_BY_ZERO
+ 69 PIO_NOT_IMPLEMENTED
+ 70 ALLOCATION_ERROR
+ 71 INTERNAL_PANIC
+ 72 OUT_OF_BOUNDS
+ 73 JIT_ERROR
+ 74 EXEC_ERROR
+ 75 ILL_INHERIT
+ 76 NO_PREV_CS
+ 77 NO_CLASS
+ 78 LEX_NOT_FOUND
+ 79 PAD_NOT_FOUND
+ 80 ATTRIB_NOT_FOUND
+ 81 GLOBAL_NOT_FOUND
+ 82 METH_NOT_FOUND
+ 83 WRITE_TO_CONSTCLASS
+ 84 NOSPAWN
+ 85 INTERNAL_NOT_IMPLEMENTED
+ 86 ERR_OVERFLOW
+ 87 LOSSY_CONVERSION
+
+=item *
+
+C<exit> throws an exception of severity C<EXCEPT_EXIT>. It takes a
+single argument for the exception type.
+
+=item *
+
+C<pushaction> pushes a subroutine object onto the control stack. If the
+control stack is unwound due to an exception (or C<popmark>, or
+subroutine return), the subroutine is invoked with an integer argument:
+C<0> means a normal return; C<1> means an exception has been raised.
+[Seems like there's lots of room for dangerous collisions here.]
+
+=back
+
+=head1 IMPLEMENTATION
+
+[I'm not convinced the control stack is the right way to handle
+exceptions. Most of Parrot is based on the continuation-passing style of
+control, shouldn't exceptions be based on it too?]
+
+=head2 Opcodes that Throw Exceptions
+
+Exceptions have been incorporated into built-in opcodes in a limited
+way, but they aren't used consistently.
+
+Divide by zero exceptions are thrown by C<div>, C<fdiv>, and C<cmod>.
+
+The C<ord> opcode throws an exception when it's passed an empty
+argument, or passed a string index that's outside the length of the
+string.
+
+The C<classoffset> opcode throws an exception when it's asked to
+retrieve the attribute offset for a class that isn't in the object's
+inheritance hierarchy.
+
+The C<find_charset> opcode throws an exception if the charset name it's
+looking up doesn't exist. The C<trans_charset> opcode throws an
+exception on "information loss" (presumably, this means when one charset
+doesn't have a one-to-one correspondence in the other charset).
+
+The C<find_encoding> opcode throws an exception if the encoding name
+it's looking up doesn't exist. The C<trans_encoding> opcode throws an
+exception on "information loss" (presumably, this means when one
+encoding doesn't have a one-to-one correspondence in the other
+encoding).
+
+Parrot's default version of the C<LexPad> PMC uses exceptions, though
+other implementations can choose to return error values instead.
+C<store_lex> throws an exception when asked to store a lexical variable
+in a name that doesn't exist. C<find_lex> throws an exception when asked
+to retrieve a lexical name that doesn't exist.
+
+Other opcodes respond to an C<errorson> setting to decide whether to
+throw an exception or return an error value. C<find_global> throws an
+exception (or returns a Null PMC) if the global name requested doesn't
+exist. C<find_name> throws an exception (or returns a Null PMC) if the
+name requested doesn't exist in a lexical, current, global, or built-in
+namespace.
+
+It's a little odd that so few opcodes throw exceptions (these are the
+ones that are documented, but a few others throw exceptions internally
+even though they aren't documented as doing so). It's worth considering
+either expanding the use of exceptions consistently throughout the
+opcode set, or eliminating exceptions from the opcode set entirely. The
+strategy for error handling should be consistent, whatever it is. [I
+like the way C<LexPad>s and the C<errorson> settings provide the option
+for exception-based or non-exception-based implementations, rather than
+forcing one or the other.]
+
+=head2 Excerpt
+
+[Excerpt from "Perl 6 and Parrot Essentials" to seed discussion.
+Out-of-date in some ways, and in others it was simply speculative.]
+
+Exceptions provide a way of calling a piece of code outside the normal
+flow of control. They are mainly used for error reporting or cleanup
+tasks, but sometimes exceptions are just a funny way to branch from
+one code location to another one.
+
+Exceptions are objects that hold all the information needed to handle
+the exception: the error message, the severity and type of the error,
+etc. The class of an exception object indicates the kind of exception
+it is.
+
+Exception handlers are derived from continuations. They are ordinary
+subroutines that follow the Parrot calling conventions, but are never
+explicitly called from within user code. User code pushes an exception
+handler onto the control stack with the C<set_eh> opcode. The system
+calls the installed exception handler only when an exception is thrown.
+
+ newsub P20, .Exception_Handler, _handler
+ set_eh P20 # push handler on control stack
+ null P10 # set register to null
+ find_global P10, "none" # may throw exception
+ clear_eh # pop the handler off the stack
+ ...
+
+ _handler: # if not, execution continues here
+ is_null P10, not_found # test P10
+ ...
+
+This example creates a new exception handler subroutine with the
+C<newsub> opcode and installs it on the control stack with the
+C<set_eh> opcode. It sets the C<P10> register to a null value (so it
+can be checked later) and attempts to retrieve the global variable
+named C<none>. If the global variable is found, the next statement
+(C<clear_eh>) pops the exception handler off the control stack and
+normal execution continues. If the C<find_global> call doesn't find
+C<none> it throws an exception by pushing an exception object onto the
+control stack. When Parrot sees that it has an exception, it pops it
+off the control stack and calls the exception handler C<_handler>.
+
+The first exception handler in the control stack sees every exception
+thrown. The handler has to examine the exception object and decide
+whether it can handle it (or discard it) or whether it should
+C<rethrow> the exception to pass it along to an exception handler
+deeper in the stack. The C<rethrow> opcode is only valid in exception
+handlers. It pushes the exception object back onto the control stack so
+Parrot knows to search for the next exception handler in the stack. The
+process continues until some exception handler deals with the exception
+and returns normally, or until there are no more exception handlers on
+the control stack. When the system finds no installed exception handlers
+it defaults to a final action, which normally means it prints an
+appropriate message and terminates the program.
+
+When the system installs an exception handler, it creates a return
+continuation with a snapshot of the current interpreter context. If
+the exception handler just returns (that is, if the exception is
+cleanly caught) the return continuation restores the control stack
+back to its state when the exception handler was called, cleaning up
+the exception handler and any other changes that were made in the
+process of handling the exception.
+
+Exceptions thrown by standard Parrot opcodes (like the one thrown by
+C<find_global> above or by the C<throw> opcode) are always resumable,
+so when the exception handler function returns normally it continues
+execution at the opcode immediately after the one that threw the
+exception. Other exceptions at the run-loop level are also generally
+resumable.
+
+ new P10, Exception # create new Exception object
+ set P10["_message"], "I die" # set message attribute
+ throw P10 # throw it
+
+Exceptions are designed to work with the Parrot calling conventions.
+Since the return addresses of C<bsr> subroutine calls and exception
+handlers are both pushed onto the control stack, it's generally a bad
+idea to combine the two.
+
+=head1 ATTACHMENTS
+
+None.
+
+=head1 FOOTNOTES
+
+None.
+
+=head1 REFERENCES
+
+ src/ops/core.ops
+ src/exceptions.c
+ runtime/parrot/include/except_types.pasm
+ runtime/parrot/include/except_severity.pasm
+
+=cut
+
+__END__
+Local Variables:
+ fill-column:78
+End:
-
[svn:parrot-pdd] r11993 - in trunk: . docs/pdds/clip
by allison