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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }