Skip to content

Instantly share code, notes, and snippets.

@wycats
Created June 4, 2014 01:13
Show Gist options
  • Save wycats/f026a7cdf9ccfe401072 to your computer and use it in GitHub Desktop.
Save wycats/f026a7cdf9ccfe401072 to your computer and use it in GitHub Desktop.
extern crate debug;
use std::mem::transmute;
use std::raw::Closure;
use std::rt::task::Task;
use std::rt::local::Local;
use std::any::{Any, AnyRefExt};
struct RawUnwinder {
unwinding: bool,
cause: Option<Box<Any:Send>>
}
#[deriving(Show)]
struct Inner {
text: String
}
#[deriving(Show)]
struct Args<'a> {
fail: bool,
first: String,
second: Vec<&'static str>,
reference: Option<&'a Inner>
}
fn main() {
let inner = Inner { text: "Heyo".to_str() };
let args = box Args { fail: false, first: "hello".to_str(), second: vec!("world", "and", "stuff"), reference: Some(&inner) };
let fail = box Args { fail: true, first: "hello".to_str(), second: vec!(), reference: None };
let success: || = unsafe {
let synth = Closure { code: transmute(testing), env: transmute(args) };
transmute(synth)
};
let failure: || = unsafe {
let synth = Closure { code: transmute(testing), env: transmute(fail) };
transmute(synth)
};
let old: Box<Task> = Local::take();
let handle: *mut Task = unsafe { *transmute::<&Box<Task>, &*mut Task>(&old) };
Local::put(old);
success();
unsafe {
let unwinder = &mut ((*handle).unwinder);
unwinder.try(success);
unwinder.try(failure);
let raw: &RawUnwinder = transmute(unwinder);
match raw.cause {
None => (),
Some(ref err) => println!("{}", cause_str(err))
}
}
}
fn testing(args: &Args) {
if args.fail { fail!("YOLO BROLO"); }
println!("{}", args);
}
fn cause_str(reason: &Box<Any:Send>) -> String {
match reason.as_ref::<&'static str>() {
Some(s) => *s,
None => match reason.as_ref::<String>() {
Some(s) => s.as_slice(),
None => "Box<Any>",
}
}.to_str()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment