annotate tango/lib/compiler/llvmdc/eh.d @ 323:0d52412d5b1a trunk

[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments. Changed the way moduleinfo is registered to use the same approach as DMD, this eliminates the need for correct linking order and should make the way for using a natively compiled runtime library. This should speed up linking tremendously and should now be possible. Fixed the llvm.used array to only be emitted if really necessary.
author lindquist
date Wed, 09 Jul 2008 23:43:51 +0200
parents e9c93739bc4c
children 5bea8a1ef905
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
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents: 318
diff changeset
7 // debug = EH_personality;
314
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
318
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
197 else if(!action_offset && landing_pad)
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
198 return _d_eh_install_finally_context(actions, landing_pad, exception_struct, context);
314
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
199
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
200 /*
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
201 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
202 */
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
203 ubyte* action_walker = action_table + action_offset - 1;
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
204
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
205 ptrdiff_t ti_offset, next_action_offset;
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
206 while(true) {
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
207 action_walker = get_sleb128(action_walker, ti_offset);
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
208 // 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
209 // 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
210 get_sleb128(action_walker, next_action_offset);
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 // negative are 'filters' which we don't use
318
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
213 assert(ti_offset >= 0 && "Filter actions are unsupported");
314
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
214
318
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
215 // zero means cleanup, which we require to be the last action
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
216 if(ti_offset == 0) {
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
217 assert(next_action_offset == 0 && "Cleanup action must be last in chain");
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
218 return _d_eh_install_finally_context(actions, landing_pad, exception_struct, context);
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
219 }
314
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 // 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
222 // exception structure is a base
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
223 ClassInfo catch_ci = classinfo_table[-ti_offset];
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
224 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
225 if(_d_isbaseof(exception_struct.exception_object.classinfo, catch_ci))
318
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
226 return _d_eh_install_catch_context(actions, ti_offset, landing_pad, exception_struct, context);
314
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
227
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
228 // 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
229 if(next_action_offset == 0)
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
230 return _Unwind_Reason_Code.CONTINUE_UNWIND;
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
231 else
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
232 action_walker += next_action_offset;
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
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
235 assert(false);
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
236 }
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
237
318
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
238 // These are the register numbers for SetGR that
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
239 // llvm's eh.exception and eh.selector intrinsics
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
240 // will pick up.
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
241 // Found by trial-and-error and probably platform dependent!
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
242 private int eh_exception_regno = 0;
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
243 private int eh_selector_regno = 2;
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
244
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
245 private _Unwind_Reason_Code _d_eh_install_catch_context(_Unwind_Action actions, ptrdiff_t switchval, ulong landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context)
314
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
246 {
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
247 debug(EH_personality) printf("Found catch clause!\n");
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
248
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
249 if(actions & _Unwind_Action.SEARCH_PHASE)
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
250 return _Unwind_Reason_Code.HANDLER_FOUND;
318
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
251
314
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
252 else if(actions & _Unwind_Action.HANDLER_PHASE)
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
253 {
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents: 318
diff changeset
254 debug(EH_personality) printf("Setting switch value to: %d!\n", switchval);
318
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
255 _Unwind_SetGR(context, eh_exception_regno, cast(ulong)cast(void*)(exception_struct.exception_object));
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
256 _Unwind_SetGR(context, eh_selector_regno, switchval);
314
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
257 _Unwind_SetIP(context, landing_pad);
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
258 return _Unwind_Reason_Code.INSTALL_CONTEXT;
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
259 }
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 assert(false);
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
262 }
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
263
318
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
264 private _Unwind_Reason_Code _d_eh_install_finally_context(_Unwind_Action actions, ulong landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context)
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
265 {
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
266 // if we're merely in search phase, continue
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
267 if(actions & _Unwind_Action.SEARCH_PHASE)
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
268 return _Unwind_Reason_Code.CONTINUE_UNWIND;
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
269
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
270 debug(EH_personality) printf("Calling cleanup routine...\n");
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
271
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
272 _Unwind_SetGR(context, eh_exception_regno, cast(ulong)exception_struct);
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents: 318
diff changeset
273 _Unwind_SetGR(context, eh_selector_regno, 0);
318
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
274 _Unwind_SetIP(context, landing_pad);
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
275 return _Unwind_Reason_Code.INSTALL_CONTEXT;
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
276 }
8e570dbe4087 [svn r339] Add cleanup handling when within an action chain and some more documentation to the eh personality function.
ChristianK
parents: 314
diff changeset
277
314
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
278 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
279 {
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
280 ubyte* data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context);
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
281
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
282 //TODO: Do proper DWARF reading here
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
283 assert(*data++ == 0xff);
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
284
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
285 assert(*data++ == 0x00);
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
286 size_t cioffset;
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
287 data = get_uleb128(data, cioffset);
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
288 ci = cast(ClassInfo*)(data + cioffset);
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
289
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
290 assert(*data++ == 0x03);
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
291 size_t callsitelength;
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
292 data = get_uleb128(data, callsitelength);
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
293 action = data + callsitelength;
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 callsite = data;
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
296 }
133
44a95ac7368a [svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff changeset
297
44a95ac7368a [svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff changeset
298 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
299 {
44a95ac7368a [svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff changeset
300 if (e !is null)
44a95ac7368a [svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff changeset
301 {
314
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
302 _d_exception* exc_struct = new _d_exception;
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
303 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
304 exc_struct.exception_object = e;
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
305 _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
306 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
307 }
44a95ac7368a [svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff changeset
308 abort();
44a95ac7368a [svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
diff changeset
309 }
314
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
310
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
311 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
312 {
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
313 _Unwind_Resume(&exception_struct.unwind_info);
8d98e42ece93 [svn r335] The basics of exception handling are in place.
ChristianK
parents: 133
diff changeset
314 }