Fix handling of cleanups while unwinding for exception throwing.

main
theraven 16 years ago
parent fb474dd7f9
commit 7d0d599241

@ -78,13 +78,6 @@ Class get_type_table_entry(struct _Unwind_Context *context,
static BOOL isKindOfClass(Class thrown, Class type, BOOL foreignException) static BOOL isKindOfClass(Class thrown, Class type, BOOL foreignException)
{ {
// Nil is a catchall, but we only want to catch things that are not foreign
// exceptions in it.
if (Nil == type)
{
return (Nil != thrown) && !foreignException;
}
do do
{ {
if (thrown == type) if (thrown == type)
@ -114,6 +107,12 @@ static BOOL check_action_record(struct _Unwind_Context *context,
if (filter > 0) if (filter > 0)
{ {
Class type = get_type_table_entry(context, lsda, filter); Class type = get_type_table_entry(context, lsda, filter);
// If the handler is a cleanup, we don't want to do mark it as a
// handler, but we might unwind through it.
if (Nil == type)
{
return YES;
}
if (isKindOfClass(thrown_class, type, foreignException)) if (isKindOfClass(thrown_class, type, foreignException))
{ {
return YES; return YES;
@ -203,12 +202,16 @@ _Unwind_Reason_Code __gnu_objc_personality_v0(int version,
// TODO: If this is a C++ exception, we can cache the lookup and cheat a // TODO: If this is a C++ exception, we can cache the lookup and cheat a
// bit // bit
id object = nil; void *object = nil;
if (!(actions & _UA_HANDLER_FRAME)) if (!(actions & _UA_HANDLER_FRAME))
{ {
struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr); struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr);
action = dwarf_eh_find_callsite(context, &lsda); action = dwarf_eh_find_callsite(context, &lsda);
// If there's no cleanup here, continue unwinding.
if (0 == action.landing_pad) { return _URC_CONTINUE_UNWIND; } if (0 == action.landing_pad) { return _URC_CONTINUE_UNWIND; }
// If there is a cleanup, we need to return the exception structure
// (not the object) to the calling frame. The exception object
object = exceptionObject;
selector = 0; selector = 0;
} }
else if (foreignException) else if (foreignException)
@ -230,7 +233,6 @@ _Unwind_Reason_Code __gnu_objc_personality_v0(int version,
object = ex->object; object = ex->object;
} }
_Unwind_SetIP(context, (unsigned long)action.landing_pad); _Unwind_SetIP(context, (unsigned long)action.landing_pad);
_Unwind_SetGR(context, __builtin_eh_return_data_regno(0), _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
(unsigned long)object); (unsigned long)object);

Loading…
Cancel
Save