Mercurial > projects > ldc
annotate tango/lib/compiler/llvmdc/eh.d @ 314:8d98e42ece93 trunk
[svn r335] The basics of exception handling are in place.
Still need to make sure calls are turned into invokes everywhere. (NewExpression for instance)
Still some rough edges and corner cases to figure out.
Needs testing!
author | ChristianK |
---|---|
date | Wed, 02 Jul 2008 22:20:18 +0200 |
parents | 44a95ac7368a |
children | 8e570dbe4087 |
rev | line source |
---|---|
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
1 /* |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
2 * Temporary exception handling stubs |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
3 */ |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
4 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
5 import util.console; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
6 |
314
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
7 //debug = EH_personality; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
8 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
9 private extern(C) void abort(); |
314
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
10 private extern(C) int printf(char*, ...); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
11 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
12 // D runtime functions |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
13 extern(C) { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
14 int _d_isbaseof(ClassInfo oc, ClassInfo c); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
15 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
16 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
17 // libunwind stuff |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
18 extern(C) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
19 { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
20 enum _Unwind_Reason_Code |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
21 { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
22 NO_REASON = 0, |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
23 FOREIGN_EXCEPTION_CAUGHT = 1, |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
24 FATAL_PHASE2_ERROR = 2, |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
25 FATAL_PHASE1_ERROR = 3, |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
26 NORMAL_STOP = 4, |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
27 END_OF_STACK = 5, |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
28 HANDLER_FOUND = 6, |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
29 INSTALL_CONTEXT = 7, |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
30 CONTINUE_UNWIND = 8 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
31 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
32 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
33 enum _Unwind_Action |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
34 { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
35 SEARCH_PHASE = 1, |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
36 CLEANUP_PHASE = 2, |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
37 HANDLER_PHASE = 3, |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
38 FORCE_UNWIND = 4 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
39 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
40 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
41 alias void* _Unwind_Context_Ptr; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
42 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
43 alias void function(_Unwind_Reason_Code, _Unwind_Exception*) _Unwind_Exception_Cleanup_Fn; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
44 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
45 struct _Unwind_Exception |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
46 { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
47 char[8] exception_class; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
48 _Unwind_Exception_Cleanup_Fn exception_cleanup; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
49 int private_1; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
50 int private_2; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
51 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
52 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
53 void _Unwind_Resume(_Unwind_Exception*); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
54 _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
55 ulong _Unwind_GetLanguageSpecificData(_Unwind_Context_Ptr context); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
56 ulong _Unwind_GetIP(_Unwind_Context_Ptr context); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
57 ulong _Unwind_SetIP(_Unwind_Context_Ptr context, ulong new_value); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
58 ulong _Unwind_SetGR(_Unwind_Context_Ptr context, int index, ulong new_value); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
59 ulong _Unwind_GetRegionStart(_Unwind_Context_Ptr context); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
60 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
61 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
62 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
63 // helpers |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
64 private ubyte* get_uleb128(ubyte* addr, ref size_t res) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
65 { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
66 res = 0; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
67 size_t bitsize = 0; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
68 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
69 // read as long as high bit is set |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
70 while(*addr & 0x80) { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
71 res |= (*addr & 0x7f) << bitsize; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
72 bitsize += 7; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
73 addr += 1; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
74 if(bitsize >= size_t.sizeof*8) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
75 throw new Exception("tried to read uleb128 that exceeded size of size_t"); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
76 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
77 // read last |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
78 if(bitsize != 0 && *addr >= 1 << size_t.sizeof*8 - bitsize) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
79 throw new Exception("tried to read uleb128 that exceeded size of size_t"); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
80 res |= (*addr) << bitsize; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
81 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
82 return addr + 1; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
83 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
84 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
85 private ubyte* get_sleb128(ubyte* addr, ref ptrdiff_t res) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
86 { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
87 res = 0; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
88 size_t bitsize = 0; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
89 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
90 // read as long as high bit is set |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
91 while(*addr & 0x80) { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
92 res |= (*addr & 0x7f) << bitsize; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
93 bitsize += 7; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
94 addr += 1; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
95 if(bitsize >= size_t.sizeof*8) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
96 throw new Exception("tried to read sleb128 that exceeded size of size_t"); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
97 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
98 // read last |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
99 if(bitsize != 0 && *addr >= 1 << size_t.sizeof*8 - bitsize) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
100 throw new Exception("tried to read sleb128 that exceeded size of size_t"); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
101 res |= (*addr) << bitsize; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
102 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
103 // take care of sign |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
104 if(bitsize < size_t.sizeof*8 && ((*addr) & 0x40)) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
105 res |= cast(ptrdiff_t)(-1) ^ ((1 << (bitsize+7)) - 1); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
106 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
107 return addr + 1; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
108 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
109 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
110 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
111 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
112 struct _d_exception |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
113 { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
114 Object exception_object; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
115 _Unwind_Exception unwind_info; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
116 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
117 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
118 char[8] _d_exception_class = "LLDCD1\0\0"; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
119 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
120 //TODO: cleanup handling |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
121 extern(C) _Unwind_Reason_Code _d_eh_personality(int ver, _Unwind_Action actions, ulong exception_class, _Unwind_Exception* exception_info, _Unwind_Context_Ptr context) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
122 { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
123 // check ver: the C++ Itanium ABI only allows ver == 1 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
124 if(ver != 1) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
125 return _Unwind_Reason_Code.FATAL_PHASE1_ERROR; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
126 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
127 // check exceptionClass |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
128 //TODO: Treat foreign exceptions with more respect |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
129 if((cast(char*)&exception_class)[0..8] != _d_exception_class) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
130 return _Unwind_Reason_Code.FATAL_PHASE1_ERROR; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
131 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
132 // find call site table, action table and classinfo table |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
133 // Note: callsite and action tables do not contain static-length |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
134 // data and will be parsed as needed |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
135 // Note: classinfo_table points past the end of the table |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
136 ubyte* callsite_table; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
137 ubyte* action_table; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
138 ClassInfo* classinfo_table; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
139 _d_getLanguageSpecificTables(context, callsite_table, action_table, classinfo_table); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
140 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
141 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
142 /* |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
143 find landing pad and action table index belonging to ip by walking |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
144 the callsite_table |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
145 */ |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
146 ubyte* callsite_walker = callsite_table; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
147 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
148 // get the instruction pointer |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
149 // will be used to find the right entry in the callsite_table |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
150 // -1 because it will point past the last instruction |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
151 ulong ip = _Unwind_GetIP(context) - 1; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
152 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
153 // address block_start is relative to |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
154 ulong region_start = _Unwind_GetRegionStart(context); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
155 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
156 // table entries |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
157 uint block_start_offset, block_size; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
158 ulong landing_pad; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
159 size_t action_offset; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
160 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
161 while(true) { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
162 // if we've gone through the list and found nothing... |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
163 if(callsite_walker >= action_table) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
164 return _Unwind_Reason_Code.CONTINUE_UNWIND; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
165 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
166 block_start_offset = *cast(uint*)callsite_walker; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
167 block_size = *(cast(uint*)callsite_walker + 1); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
168 landing_pad = *(cast(uint*)callsite_walker + 2); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
169 if(landing_pad) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
170 landing_pad += region_start; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
171 callsite_walker = get_uleb128(callsite_walker + 3*uint.sizeof, action_offset); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
172 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
173 debug(EH_personality_verbose) printf("%d %d %d\n", block_start_offset, block_size, landing_pad); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
174 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
175 // since the list is sorted, as soon as we're past the ip |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
176 // there's no handler to be found |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
177 if(ip < region_start + block_start_offset) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
178 return _Unwind_Reason_Code.CONTINUE_UNWIND; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
179 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
180 // if we've found our block, exit |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
181 if(ip < region_start + block_start_offset + block_size) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
182 break; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
183 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
184 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
185 debug(EH_personality) printf("Found correct landing pad and actionOffset %d\n", action_offset); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
186 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
187 // now we need the exception's classinfo to find a handler |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
188 // the exceptionObject is actually a member of a larger struct that |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
189 // the runtime allocated. get that now |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
190 _d_exception* exception_struct = cast(_d_exception*)(cast(ubyte*)exception_info - _d_exception.unwind_info.offsetof); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
191 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
192 // if there's no actionOffset and no landingpad, continue unwinding |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
193 if(!action_offset && !landing_pad) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
194 return _Unwind_Reason_Code.CONTINUE_UNWIND; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
195 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
196 // if there's no action offset but a landing pad, this is a cleanup handler |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
197 else if(!action_offset && landing_pad) { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
198 // but only if we're asked to! |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
199 if(!(actions & _Unwind_Action.CLEANUP_PHASE)) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
200 return _Unwind_Reason_Code.CONTINUE_UNWIND; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
201 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
202 debug(EH_personality) printf("Calling cleanup routine...\n"); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
203 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
204 _Unwind_SetGR(context, 0, cast(ulong)exception_struct); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
205 _Unwind_SetIP(context, landing_pad); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
206 return _Unwind_Reason_Code.INSTALL_CONTEXT; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
207 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
208 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
209 /* |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
210 walk action table chain, comparing classinfos using _d_isbaseof |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
211 */ |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
212 ubyte* action_walker = action_table + action_offset - 1; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
213 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
214 ptrdiff_t ti_offset, next_action_offset; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
215 while(true) { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
216 action_walker = get_sleb128(action_walker, ti_offset); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
217 // it is intentional that we not modify action_walker here |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
218 // next_action_offset is from current action_walker position |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
219 get_sleb128(action_walker, next_action_offset); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
220 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
221 // negative are 'filters' which we don't use |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
222 assert(ti_offset >= 0); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
223 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
224 //TODO: Implement cleanups |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
225 assert(ti_offset != 0); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
226 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
227 // get classinfo for action and check if the one in the |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
228 // exception structure is a base |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
229 ClassInfo catch_ci = classinfo_table[-ti_offset]; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
230 debug(EH_personality) printf("Comparing catch %s to exception %s\n", catch_ci.name.ptr, exception_struct.exception_object.classinfo.name.ptr); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
231 if(_d_isbaseof(exception_struct.exception_object.classinfo, catch_ci)) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
232 return _d_eh_success(actions, ti_offset, landing_pad, exception_struct, context); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
233 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
234 // we've walked through all actions and found nothing... |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
235 if(next_action_offset == 0) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
236 return _Unwind_Reason_Code.CONTINUE_UNWIND; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
237 else |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
238 action_walker += next_action_offset; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
239 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
240 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
241 assert(false); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
242 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
243 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
244 private _Unwind_Reason_Code _d_eh_success(_Unwind_Action actions, ptrdiff_t switchval, ulong landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
245 { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
246 debug(EH_personality) printf("Found catch clause!\n"); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
247 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
248 if(actions & _Unwind_Action.SEARCH_PHASE) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
249 return _Unwind_Reason_Code.HANDLER_FOUND; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
250 else if(actions & _Unwind_Action.HANDLER_PHASE) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
251 { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
252 //TODO: Set sensible value for eh_ptr |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
253 _Unwind_SetGR(context, 0, cast(ulong)cast(void*)(exception_struct.exception_object)); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
254 _Unwind_SetGR(context, 2, switchval); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
255 _Unwind_SetIP(context, landing_pad); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
256 return _Unwind_Reason_Code.INSTALL_CONTEXT; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
257 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
258 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
259 assert(false); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
260 } |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
261 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
262 private void _d_getLanguageSpecificTables(_Unwind_Context_Ptr context, ref ubyte* callsite, ref ubyte* action, ref ClassInfo* ci) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
263 { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
264 ubyte* data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
265 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
266 //TODO: Do proper DWARF reading here |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
267 assert(*data++ == 0xff); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
268 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
269 assert(*data++ == 0x00); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
270 size_t cioffset; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
271 data = get_uleb128(data, cioffset); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
272 ci = cast(ClassInfo*)(data + cioffset); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
273 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
274 assert(*data++ == 0x03); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
275 size_t callsitelength; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
276 data = get_uleb128(data, callsitelength); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
277 action = data + callsitelength; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
278 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
279 callsite = data; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
280 } |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
281 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
282 extern(C) void _d_throw_exception(Object e) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
283 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
284 if (e !is null) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
285 { |
314
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
286 _d_exception* exc_struct = new _d_exception; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
287 exc_struct.unwind_info.exception_class[] = _d_exception_class; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
288 exc_struct.exception_object = e; |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
289 _Unwind_Reason_Code ret = _Unwind_RaiseException(&exc_struct.unwind_info); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
290 console("_Unwind_RaiseException failed with reason code: ")(ret)("\n"); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
291 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
292 abort(); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff
changeset
|
293 } |
314
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
294 |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
295 extern(C) void _d_eh_resume_unwind(_d_exception* exception_struct) |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
296 { |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
297 _Unwind_Resume(&exception_struct.unwind_info); |
8d98e42ece93
[svn r335] The basics of exception handling are in place.
ChristianK
parents:
133
diff
changeset
|
298 } |