@@ -17,7 +17,7 @@ use borrow;
1717use cast:: transmute;
1818use cleanup;
1919use local_data;
20- use libc:: { c_void, uintptr_t} ;
20+ use libc:: { c_void, uintptr_t, c_char , size_t } ;
2121use prelude:: * ;
2222use option:: { Option , Some , None } ;
2323use rt:: borrowck;
@@ -465,6 +465,48 @@ impl Unwinder {
465465 }
466466}
467467
468+ /// This is the entry point of unwinding for things like lang items and such.
469+ /// The arguments are normally generated by the compiler.
470+ pub fn begin_unwind ( msg : * c_char , file : * c_char , line : size_t ) -> ! {
471+ use rt:: in_green_task_context;
472+ use rt:: task:: Task ;
473+ use rt:: local:: Local ;
474+ use rt:: logging:: Logger ;
475+ use str:: Str ;
476+ use c_str:: CString ;
477+
478+ unsafe {
479+ let msg = CString :: new ( msg, false ) ;
480+ let file = CString :: new ( file, false ) ;
481+ let msg = match msg. as_str ( ) {
482+ Some ( s) => s, None => rtabort ! ( "message wasn't utf8?" )
483+ } ;
484+ let file = match file. as_str ( ) {
485+ Some ( s) => s, None => rtabort ! ( "message wasn't utf8?" )
486+ } ;
487+
488+ if in_green_task_context ( ) {
489+ // Be careful not to allocate in this block, if we're failing we may
490+ // have been failing due to a lack of memory in the first place...
491+ do Local :: borrow |task: & mut Task | {
492+ let n = task. name . as_ref ( ) . map ( |n| n. as_slice ( ) ) . unwrap_or ( "<unnamed>" ) ;
493+ format_args ! ( |args| { task. logger. log( args) } ,
494+ "task '{}' failed at '{}', {}:{}" ,
495+ n, msg, file, line) ;
496+ }
497+ } else {
498+ rterrln ! ( "failed in non-task context at '{}', {}:{}" ,
499+ msg, file, line as int) ;
500+ }
501+
502+ let task: * mut Task = Local :: unsafe_borrow ( ) ;
503+ if ( * task) . unwinder . unwinding {
504+ rtabort ! ( "unwinding again" ) ;
505+ }
506+ ( * task) . unwinder . begin_unwind ( ) ;
507+ }
508+ }
509+
468510#[ cfg( test) ]
469511mod test {
470512 use rt:: test:: * ;
0 commit comments