Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base: master
...
compare: exceptions_refactor_merge
Checking mergeability… Don't worry, you can still create the pull request.
  • 8 commits
  • 6 files changed
  • 0 commit comments
  • 2 contributors
Commits on Feb 23, 2010
@tene tene Create a branch for exceptions refactoring work.
git-svn-id: https://svn.parrot.org/parrot/branches/exceptions_refactor@44391 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
dae8e2a
Commits on Feb 25, 2010
@tene tene Allow subclasses of Exception to be thrown
git-svn-id: https://svn.parrot.org/parrot/branches/exceptions_refactor@44469 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
5e92f4b
Commits on Feb 27, 2010
@tene tene Allow rethrowing subclasses of exception.
Add additional information to backtraces. (still needs docs update)

git-svn-id: https://svn.parrot.org/parrot/branches/exceptions_refactor@44533 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
33223bd
Commits on Mar 01, 2010
@tene tene Allow rethrown subclassed exceptions to find the next handler.
Add infrastructure to filter based on exception types.

git-svn-id: https://svn.parrot.org/parrot/branches/exceptions_refactor@44555 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
4972016
@tene tene Refactor ExceptionHandler to use one array instead of four.
git-svn-id: https://svn.parrot.org/parrot/branches/exceptions_refactor@44575 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
dd01b18
Commits on Mar 02, 2010
@tene tene Work around a bug somewhere with attributes in subclasses of PMCs.
git-svn-id: https://svn.parrot.org/parrot/branches/exceptions_refactor@44577 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
69ff507
Commits on Dec 01, 2010
@leto leto Attempt to merge branch 'master' into exceptions_refactor
This doesn't compile yet.

Conflicts:
	src/ops/core.ops
	src/pmc/exceptionhandler.pmc
	src/scheduler.c
9073bda
@leto leto [t] Add tests for throwing subclasses of Exception, tene++ 416e564
View
4 src/ops/core.ops
@@ -743,7 +743,7 @@ inline op throw(invar PMC) :flow {
EXCEPTION_UNIMPLEMENTED,
Parrot_str_new_constant(interp, "Not a throwable object"));
- VTABLE_set_attr_str(interp, except, Parrot_str_new_constant(interp, "resume"), resume);
+ VTABLE_set_pmc_keyed_str(interp, except, Parrot_str_new_constant(interp, "resume"), resume);
dest = Parrot_ex_throw_from_op(interp, except, ret);
goto ADDRESS(dest);
}
@@ -751,7 +751,7 @@ inline op throw(invar PMC) :flow {
inline op throw(invar PMC, invar PMC) :flow {
opcode_t * dest;
PMC * except = $1;
- if (PMC_IS_NULL(except) || except->vtable->base_type != enum_class_Exception)
+ if (PMC_IS_NULL(except) || ! VTABLE_isa(interp, except, Parrot_str_new_constant(interp, "Exception")))
except = Parrot_ex_build_exception(interp, EXCEPT_fatal,
EXCEPTION_UNIMPLEMENTED,
Parrot_str_new_constant(interp, "Not a throwable object"));
View
11 src/pmc/callcontext.pmc
@@ -1581,6 +1581,7 @@ sub, or for the point of the call a level deeper for the rest.
while (cur_ctx) {
PMC * const frame = Parrot_pmc_new(INTERP, enum_class_Hash);
PMC *annotations = NULL;
+ Parrot_Context_info info;
Parrot_Sub_attributes *sub;
/* Get sub and put it in the hash. */
@@ -1612,6 +1613,16 @@ sub, or for the point of the call a level deeper for the rest.
VTABLE_set_pmc_keyed_str(INTERP, frame, CONST_STRING(INTERP, "annotations"), annotations);
+ if (Parrot_Context_get_info(interp, cur_ctx, &info)) {
+ PMC *hash = Parrot_pmc_new(interp, enum_class_Hash);
+ VTABLE_set_string_keyed_str(interp, hash, CONST_STRING(interp, "fullname"), info.fullname);
+ VTABLE_set_string_keyed_str(interp, hash, CONST_STRING(interp, "nsname"), info.nsname);
+ VTABLE_set_string_keyed_str(interp, hash, CONST_STRING(interp, "subname"), info.subname);
+ VTABLE_set_integer_keyed_str(interp, hash, CONST_STRING(interp, "pc"), info.pc);
+ VTABLE_set_string_keyed_str(interp, hash, CONST_STRING(interp, "file"), info.file);
+ VTABLE_set_integer_keyed_str(interp, hash, CONST_STRING(interp, "line"), info.line);
+ VTABLE_set_pmc_keyed_str(interp, frame, CONST_STRING(interp, "info"), hash);
+ }
/* Push frame and go to next caller. */
VTABLE_push_pmc(INTERP, result, frame);
cur_ctx = Parrot_pcc_get_caller_ctx(INTERP, cur_ctx);
View
14 src/pmc/exception.pmc
@@ -493,6 +493,20 @@ Sets the PMC value for C<*key>.
/*
+=item C<void set_pmc_keyed_str(STRING *key, PMC *value)>
+
+Sets the PMC value for C<*key>.
+
+=cut
+
+*/
+
+ VTABLE void set_pmc_keyed_str(STRING *key, PMC *value) {
+ SELF.set_attr_str(key, value);
+ }
+
+/*
+
=item C<void set_pointer(void *context)>
Store a context for the handler iterator.
View
85 src/pmc/exceptionhandler.pmc
@@ -27,8 +27,9 @@ exception object's C<_P5> attribute.
pmclass ExceptionHandler extends Continuation provides invokable auto_attrs {
- ATTR PMC *handled_types;
- ATTR PMC *handled_types_except;
+ ATTR PMC *handled_items;
+ ATTR INTVAL inclusive;
+ ATTR INTVAL class_based;
ATTR INTVAL min_severity;
ATTR INTVAL max_severity;
@@ -48,8 +49,9 @@ Initializes the exception handler.
attrs->invoked = 0;
attrs->min_severity = 0;
attrs->max_severity = 0;
- attrs->handled_types = PMCNULL;
- attrs->handled_types_except = PMCNULL;
+ attrs->inclusive = -1;
+ attrs->class_based = -1;
+ attrs->handled_items = PMCNULL;
/* an exception handler has no separate context; it's only a snapshot
* of an "earlier" context, which is contained in the interpreter's
@@ -183,13 +185,12 @@ Report whether the exception handler can handle a particular type of exception.
if (exception->vtable->base_type == enum_class_Exception
|| VTABLE_isa(INTERP, exception, ex_str)) {
- PMC *handled_types;
- PMC *handled_types_except;
- INTVAL min_severity, max_severity;
- GET_ATTR_handled_types(INTERP, SELF, handled_types);
- GET_ATTR_handled_types_except(INTERP, SELF, handled_types_except);
+ PMC *handled_items;
+ INTVAL inclusive, min_severity, max_severity;
+ GET_ATTR_handled_items(INTERP, SELF, handled_items);
GET_ATTR_max_severity(INTERP, SELF, max_severity);
GET_ATTR_min_severity(INTERP, SELF, min_severity);
+ GET_ATTR_inclusive(INTERP, SELF, inclusive);
if (severity < min_severity) {
RETURN(INTVAL 0);
@@ -201,29 +202,17 @@ Report whether the exception handler can handle a particular type of exception.
const INTVAL elems = VTABLE_elements(INTERP, handled_types);
const INTVAL type = VTABLE_get_integer_keyed_str(INTERP, exception, CONST_STRING(INTERP, "type"));
INTVAL i;
+ INTVAL match = inclusive ? 1 : 0;
+ INTVAL not_match = inclusive ? 0 : 1;
for (i = 0; i < elems; ++i) {
INTVAL handled_type = VTABLE_get_integer_keyed_int(INTERP,
handled_types, i);
if (handled_type == type)
- RETURN(INTVAL 1);
+ RETURN(INTVAL match);
}
- RETURN(INTVAL 0);
- }
- if (handled_types_except != PMCNULL) {
- const INTVAL elems = VTABLE_elements(INTERP, handled_types_except);
- const INTVAL type = VTABLE_get_integer_keyed_str(INTERP, exception, CONST_STRING(INTERP, "type"));
- INTVAL i;
-
- for (i = 0; i < elems; ++i) {
- const INTVAL handled_type = VTABLE_get_integer_keyed_int(INTERP,
- handled_types_except, i);
- if (handled_type == type)
- RETURN(INTVAL 0);
- }
-
- RETURN(INTVAL 1);
+ RETURN(INTVAL not_match);
}
else if (max_severity > 0 || min_severity > 0) {
RETURN(INTVAL 1);
@@ -296,6 +285,8 @@ Set the exception types that the ExceptionHandler will handle.
VTABLE_elements(INTERP, types) > 0
? types
: PMCNULL;
+ attrs->inclusive = 1;
+ attrs->class_based = 0;
}
/*
@@ -315,6 +306,50 @@ Set the exception types that the ExceptionHandler will not handle.
VTABLE_elements(INTERP, types) > 0
? types
: PMCNULL;
+ attrs->inclusive = 0;
+ attrs->class_based = 0;
+ }
+
+/*
+
+=item C<METHOD handle_classes(PMC *classes :slurpy)>
+
+Set the exception classes that the ExceptionHandler will handle.
+
+=cut
+
+*/
+
+ METHOD handle_classes(PMC *classes :slurpy) {
+ Parrot_ExceptionHandler_attributes * const attrs =
+ PARROT_EXCEPTIONHANDLER(SELF);
+ attrs->handled_items =
+ VTABLE_elements(interp, classes) > 0
+ ? classes
+ : PMCNULL;
+ attrs->inclusive = 1;
+ attrs->class_based = 1;
+ }
+
+/*
+
+=item C<METHOD handle_classes_except(PMC *classes :slurpy)>
+
+Set the exception classes that the ExceptionHandler will not handle.
+
+=cut
+
+*/
+
+ METHOD handle_classes_except(PMC *classes :slurpy) {
+ Parrot_ExceptionHandler_attributes * const attrs =
+ PARROT_EXCEPTIONHANDLER(SELF);
+ attrs->handled_items =
+ VTABLE_elements(interp, classes) > 0
+ ? classes
+ : PMCNULL;
+ attrs->inclusive = 0;
+ attrs->class_based = 1;
}
}
View
13 src/scheduler.c
@@ -858,9 +858,10 @@ Parrot_cx_find_handler_local(PARROT_INTERP, ARGIN(PMC *task))
static PMC * keep_context = NULL;
PMC *context;
- PMC *iter = PMCNULL;
- STRING * const handled_str = CONST_STRING(interp, "handled");
- STRING * const handler_iter_str = CONST_STRING(interp, "handler_iter");
+ PMC *iter = PMCNULL;
+ STRING * const handled_str = CONST_STRING(interp, "handled");
+ STRING * const iter_str = CONST_STRING(interp, "handler_iter");
+ STRING * const ex_str = CONST_STRING(interp, "Exception");
if (already_doing) {
Parrot_io_eprintf(interp,
@@ -883,9 +884,9 @@ Parrot_cx_find_handler_local(PARROT_INTERP, ARGIN(PMC *task))
/* Exceptions store the handler iterator for rethrow, other kinds of
* tasks don't (though they could). */
- if (task->vtable->base_type == enum_class_Exception
+ if (VTABLE_isa(interp, task, ex_str)
&& VTABLE_get_integer_keyed_str(interp, task, handled_str) == -1) {
- iter = VTABLE_get_attr_str(interp, task, handler_iter_str);
+ iter = VTABLE_get_attr_str(interp, task, iter_str);
context = (PMC *)VTABLE_get_pointer(interp, task);
}
else {
@@ -909,7 +910,7 @@ Parrot_cx_find_handler_local(PARROT_INTERP, ARGIN(PMC *task))
if (valid_handler) {
if (task->vtable->base_type == enum_class_Exception) {
/* Store iterator and context for a later rethrow. */
- VTABLE_set_attr_str(interp, task, handler_iter_str, iter);
+ VTABLE_set_attr_str(interp, task, iter_str, iter);
VTABLE_set_pointer(interp, task, context);
}
--already_doing;
View
38 t/pmc/exception.t
@@ -19,7 +19,7 @@ Tests C<Exception> and C<ExceptionHandler> PMCs.
.sub main :main
.include 'test_more.pir'
- plan(43)
+ plan(47)
test_bool()
test_int()
test_integer_keyed()
@@ -38,6 +38,36 @@ Tests C<Exception> and C<ExceptionHandler> PMCs.
test_throw_clone()
test_backtrace()
test_annotations()
+ test_throw_exception_subclass()
+.end
+
+.sub test_throw_exception_subclass
+ .local pmc exc, lexc, lex
+ exc = get_class 'Exception'
+ lexc = subclass exc, 'LolException'
+ lex = new lexc
+ lex['message'] = 'I CAN HAZ LOLEXCEPTION?'
+ $S0 = lex['message']
+
+ push_eh gotit
+ die $S0
+
+ throw lex
+ pop_eh
+
+ .return()
+ gotit:
+ .local pmc ex, cont
+ .local string msg, type, loltype
+ .get_results(ex)
+ type = typeof ex
+ loltype = typeof lex
+ is(type,loltype, 'throwing a subclass of Exception has the correct type')
+
+ msg = ex
+ is(msg,'I CAN HAZ LOLEXCEPTION?', 'throwing a subclass of Exception has the correct message')
+ cont = ex['resume']
+ cont()
.end
.sub test_bool
@@ -410,6 +440,12 @@ _handler:
is($I0, 0, 'annotations from unthrow Exception are empty')
.end
+.namespace ['LolException']
+
+.sub 'lol' :method
+ say 'OHAI'
+.end
+
# Local Variables:
# mode: pir
# fill-column: 100

No commit comments for this range

Something went wrong with that request. Please try again.