-
Notifications
You must be signed in to change notification settings - Fork 2
/
ExceptionDispatcher.java
69 lines (64 loc) · 2.7 KB
/
ExceptionDispatcher.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package Rakudo.Runtime.Exceptions;
import Rakudo.Metamodel.Hints;
import Rakudo.Metamodel.RakudoObject;
import Rakudo.Metamodel.Representations.RakudoCodeRef;
import Rakudo.Runtime.CaptureHelper;
import Rakudo.Runtime.Exceptions.LeaveStackUnwinderException;
import Rakudo.Runtime.ThreadContext;
import Rakudo.Runtime.Ops;
/// <summary>
/// Various bits of logic relating to exception dispatch.
/// </summary>
public class ExceptionDispatcher // C# has public static
{
/// <summary>
/// Invokes the specified exception handler with the given exception
/// object.
/// </summary>
/// <param name="Handler"></param>
/// <param name="ExceptionObject"></param>
/// <returns></returns>
public static RakudoObject CallHandler(ThreadContext TC, RakudoObject Handler, RakudoObject ExceptionObject)
{
// Invoke the handler. Note that in some cases we never return from it;
// for example, the return exception handler does .leave.
RakudoObject Returned = Handler.getSTable().Invoke.Invoke(TC, Handler, CaptureHelper.FormWith(new RakudoObject[] { ExceptionObject }));
// So, we returned. Let's see if it's resumable.
RakudoObject ResumableMeth = Returned.getSTable().FindMethod.FindMethod(TC, Returned, "resumable", Hints.NO_HINT);
RakudoObject Resumable = ResumableMeth.getSTable().Invoke.Invoke(TC, ResumableMeth, CaptureHelper.FormWith(new RakudoObject[] { Returned }));
if (Ops.unbox_int(TC, Resumable) != 0)
{
// Resumable, so don't need to stack unwind. Simply return
// from here.
return Returned;
}
else
{
// Not resumable, so stack unwind out of the block containing
// the handler.
throw new LeaveStackUnwinderException(
((RakudoCodeRef.Instance)Handler).OuterBlock,
Returned);
}
}
/// <summary>
/// Dies from an unhandled exception.
/// </summary>
/// <param name="Exception"></param>
public static void DieFromUnhandledException(ThreadContext TC, RakudoObject Exception)
{
// Try to stringify the exception object.
try
{
RakudoObject StrMeth = Exception.getSTable().FindMethod.FindMethod(TC, Exception, "Str", Hints.NO_HINT);
RakudoObject Stringified = StrMeth.getSTable().Invoke.Invoke(TC, StrMeth, CaptureHelper.FormWith(new RakudoObject[] { Exception }));
System.out.println(Ops.unbox_str(TC, Stringified));
}
catch ( Exception ex )
{
System.err.println("Died from an exception, and died trying to stringify it too.");
}
// Exit with an error code.
System.exit(1);
}
}