Mercurial > projects > ldc
comparison runtime/internal/eh.d @ 895:fb4853c46917
Apply pcwalton's eh runtime portability fix.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Mon, 19 Jan 2009 19:42:00 +0100 |
parents | aa953cc960b6 |
children | c6f16c3f377b |
comparison
equal
deleted
inserted
replaced
894:77a3d6945f81 | 895:fb4853c46917 |
---|---|
60 | 60 |
61 struct _Unwind_Exception | 61 struct _Unwind_Exception |
62 { | 62 { |
63 char[8] exception_class; | 63 char[8] exception_class; |
64 _Unwind_Exception_Cleanup_Fn exception_cleanup; | 64 _Unwind_Exception_Cleanup_Fn exception_cleanup; |
65 int private_1; | 65 ptrdiff_t private_1; |
66 int private_2; | 66 ptrdiff_t private_2; |
67 } | 67 } |
68 | 68 |
69 version(X86_UNWIND) | 69 version(X86_UNWIND) |
70 { | 70 { |
71 void _Unwind_Resume(_Unwind_Exception*); | 71 void _Unwind_Resume(_Unwind_Exception*); |
72 _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*); | 72 _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*); |
73 ulong _Unwind_GetLanguageSpecificData(_Unwind_Context_Ptr context); | 73 ptrdiff_t _Unwind_GetLanguageSpecificData(_Unwind_Context_Ptr context); |
74 ulong _Unwind_GetIP(_Unwind_Context_Ptr context); | 74 ptrdiff_t _Unwind_GetIP(_Unwind_Context_Ptr context); |
75 ulong _Unwind_SetIP(_Unwind_Context_Ptr context, ulong new_value); | 75 ptrdiff_t _Unwind_SetIP(_Unwind_Context_Ptr context, ptrdiff_t new_value); |
76 ulong _Unwind_SetGR(_Unwind_Context_Ptr context, int index, ulong new_value); | 76 ptrdiff_t _Unwind_SetGR(_Unwind_Context_Ptr context, int index, |
77 ulong _Unwind_GetRegionStart(_Unwind_Context_Ptr context); | 77 ptrdiff_t new_value); |
78 ptrdiff_t _Unwind_GetRegionStart(_Unwind_Context_Ptr context); | |
78 } | 79 } |
79 else | 80 else |
80 { | 81 { |
81 // runtime calls these directly | 82 // runtime calls these directly |
82 void _Unwind_Resume(_Unwind_Exception*) | 83 void _Unwind_Resume(_Unwind_Exception*) |
206 ubyte* callsite_walker = callsite_table; | 207 ubyte* callsite_walker = callsite_table; |
207 | 208 |
208 // get the instruction pointer | 209 // get the instruction pointer |
209 // will be used to find the right entry in the callsite_table | 210 // will be used to find the right entry in the callsite_table |
210 // -1 because it will point past the last instruction | 211 // -1 because it will point past the last instruction |
211 ulong ip = _Unwind_GetIP(context) - 1; | 212 ptrdiff_t ip = _Unwind_GetIP(context) - 1; |
212 | 213 |
213 // address block_start is relative to | 214 // address block_start is relative to |
214 ulong region_start = _Unwind_GetRegionStart(context); | 215 ptrdiff_t region_start = _Unwind_GetRegionStart(context); |
215 | 216 |
216 // table entries | 217 // table entries |
217 uint block_start_offset, block_size; | 218 uint block_start_offset, block_size; |
218 ulong landing_pad; | 219 ptrdiff_t landing_pad; |
219 size_t action_offset; | 220 size_t action_offset; |
220 | 221 |
221 while(true) { | 222 while(true) { |
222 // if we've gone through the list and found nothing... | 223 // if we've gone through the list and found nothing... |
223 if(callsite_walker >= action_table) | 224 if(callsite_walker >= action_table) |
228 landing_pad = *(cast(uint*)callsite_walker + 2); | 229 landing_pad = *(cast(uint*)callsite_walker + 2); |
229 if(landing_pad) | 230 if(landing_pad) |
230 landing_pad += region_start; | 231 landing_pad += region_start; |
231 callsite_walker = get_uleb128(callsite_walker + 3*uint.sizeof, action_offset); | 232 callsite_walker = get_uleb128(callsite_walker + 3*uint.sizeof, action_offset); |
232 | 233 |
233 debug(EH_personality_verbose) printf("%d %d %d\n", block_start_offset, block_size, landing_pad); | 234 debug(EH_personality_verbose) printf("ip=%llx %d %d %llx\n", ip, block_start_offset, block_size, landing_pad); |
234 | 235 |
235 // since the list is sorted, as soon as we're past the ip | 236 // since the list is sorted, as soon as we're past the ip |
236 // there's no handler to be found | 237 // there's no handler to be found |
237 if(ip < region_start + block_start_offset) | 238 if(ip < region_start + block_start_offset) |
238 return _Unwind_Reason_Code.CONTINUE_UNWIND; | 239 return _Unwind_Reason_Code.CONTINUE_UNWIND; |
309 } else { | 310 } else { |
310 private int eh_exception_regno = 0; | 311 private int eh_exception_regno = 0; |
311 private int eh_selector_regno = 2; | 312 private int eh_selector_regno = 2; |
312 } | 313 } |
313 | 314 |
314 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) | 315 private _Unwind_Reason_Code _d_eh_install_catch_context(_Unwind_Action actions, ptrdiff_t switchval, ptrdiff_t landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context) |
315 { | 316 { |
316 debug(EH_personality) printf("Found catch clause!\n"); | 317 debug(EH_personality) printf("Found catch clause!\n"); |
317 | 318 |
318 if(actions & _Unwind_Action.SEARCH_PHASE) | 319 if(actions & _Unwind_Action.SEARCH_PHASE) |
319 return _Unwind_Reason_Code.HANDLER_FOUND; | 320 return _Unwind_Reason_Code.HANDLER_FOUND; |
320 | 321 |
321 else if(actions & _Unwind_Action.HANDLER_PHASE) | 322 else if(actions & _Unwind_Action.HANDLER_PHASE) |
322 { | 323 { |
323 debug(EH_personality) printf("Setting switch value to: %d!\n", switchval); | 324 debug(EH_personality) printf("Setting switch value to: %d!\n", switchval); |
324 _Unwind_SetGR(context, eh_exception_regno, cast(ulong)cast(void*)(exception_struct.exception_object)); | 325 _Unwind_SetGR(context, eh_exception_regno, cast(ptrdiff_t)cast(void*)(exception_struct.exception_object)); |
325 _Unwind_SetGR(context, eh_selector_regno, cast(ulong)switchval); | 326 _Unwind_SetGR(context, eh_selector_regno, cast(ptrdiff_t)switchval); |
326 _Unwind_SetIP(context, landing_pad); | 327 _Unwind_SetIP(context, landing_pad); |
327 return _Unwind_Reason_Code.INSTALL_CONTEXT; | 328 return _Unwind_Reason_Code.INSTALL_CONTEXT; |
328 } | 329 } |
329 | 330 |
330 fatalerror("reached unreachable"); | 331 fatalerror("reached unreachable"); |
331 return _Unwind_Reason_Code.FATAL_PHASE2_ERROR; | 332 return _Unwind_Reason_Code.FATAL_PHASE2_ERROR; |
332 } | 333 } |
333 | 334 |
334 private _Unwind_Reason_Code _d_eh_install_finally_context(_Unwind_Action actions, ulong landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context) | 335 private _Unwind_Reason_Code _d_eh_install_finally_context(_Unwind_Action actions, ptrdiff_t landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context) |
335 { | 336 { |
336 // if we're merely in search phase, continue | 337 // if we're merely in search phase, continue |
337 if(actions & _Unwind_Action.SEARCH_PHASE) | 338 if(actions & _Unwind_Action.SEARCH_PHASE) |
338 return _Unwind_Reason_Code.CONTINUE_UNWIND; | 339 return _Unwind_Reason_Code.CONTINUE_UNWIND; |
339 | 340 |
340 debug(EH_personality) printf("Calling cleanup routine...\n"); | 341 debug(EH_personality) printf("Calling cleanup routine...\n"); |
341 | 342 |
342 _Unwind_SetGR(context, eh_exception_regno, cast(ulong)exception_struct); | 343 _Unwind_SetGR(context, eh_exception_regno, cast(ptrdiff_t)exception_struct); |
343 _Unwind_SetGR(context, eh_selector_regno, 0); | 344 _Unwind_SetGR(context, eh_selector_regno, 0); |
344 _Unwind_SetIP(context, landing_pad); | 345 _Unwind_SetIP(context, landing_pad); |
345 return _Unwind_Reason_Code.INSTALL_CONTEXT; | 346 return _Unwind_Reason_Code.INSTALL_CONTEXT; |
346 } | 347 } |
347 | 348 |