core: Start on a stack walker

This commit is contained in:
Brian Anderson 2012-06-05 18:47:18 -07:00
parent 231097960c
commit 5f4837ad6a
5 changed files with 94 additions and 5 deletions

View File

@ -201,7 +201,7 @@ mod extfmt;
mod unicode;
mod priv;
mod cmath;
mod stackwalk;
// Local Variables:
// mode: rust;

54
src/libcore/stackwalk.rs Normal file
View File

@ -0,0 +1,54 @@
import libc::uintptr_t;
class frame {
let fp: uintptr_t;
new(fp: uintptr_t) {
self.fp = fp;
}
}
fn walk_stack(visit: fn(frame) -> bool) {
frame_address { |frame_pointer|
let frame_address = unsafe {
unsafe::reinterpret_cast(frame_pointer)
};
visit(frame(frame_address));
}
}
#[test]
fn test() {
for walk_stack { |frame|
#debug("frame: %x", frame.fp);
// breakpoint();
}
}
fn breakpoint() {
rustrt::rust_dbg_breakpoint()
}
fn frame_address(f: fn(*u8)) {
rusti::frame_address(f)
}
native mod rustrt {
fn rust_dbg_breakpoint();
}
// FIXME: Unconditionalize after snapshot
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
#[abi = "rust-intrinsic"]
native mod rusti {
fn frame_address(f: fn(*u8));
}
#[cfg(stage0)]
mod rusti {
fn frame_address(_f: fn(*u8)) {
fail;
}
}

View File

@ -875,7 +875,27 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::native_item,
"frame_address" {
let frameaddress = ccx.intrinsics.get("llvm.frameaddress");
let frameaddress_val = Call(bcx, frameaddress, [C_i32(0i32)]);
Store(bcx, frameaddress_val, fcx.llretptr);
let fty = ty::mk_fn(bcx.tcx(), {
purity: ast::impure_fn,
proto: ast::proto_any,
inputs: [{
mode: ast::expl(ast::by_val),
ty: ty::mk_imm_ptr(
bcx.tcx(),
ty::mk_mach_uint(bcx.tcx(), ast::ty_u8))
}],
output: ty::mk_nil(bcx.tcx()),
ret_style: ast::return_val,
constraints: []
});
bcx = trans_call_inner(bcx, none, fty, ty::mk_nil(bcx.tcx()),
{ |bcx|
lval_no_env(
bcx,
get_param(decl, first_real_arg),
temporary)
},
arg_vals([frameaddress_val]), ignore);
}
}
build_return(bcx);

View File

@ -2318,7 +2318,20 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::native_item) {
(1u, [arg(ast::by_ref, visitor_iface)], ty::mk_nil(tcx))
}
"frame_address" {
(0u, [], ty::mk_imm_ptr(tcx, ty::mk_mach_uint(tcx, ast::ty_u8)))
let fty = ty::mk_fn(ccx.tcx, {
purity: ast::impure_fn,
proto: ast::proto_any,
inputs: [{
mode: ast::expl(ast::by_val),
ty: ty::mk_imm_ptr(
ccx.tcx,
ty::mk_mach_uint(ccx.tcx, ast::ty_u8))
}],
output: ty::mk_nil(ccx.tcx),
ret_style: ast::return_val,
constraints: []
});
(0u, [arg(ast::by_ref, fty)], ty::mk_nil(tcx))
}
other {
tcx.sess.span_err(it.span, "unrecognized intrinsic function: `" +

View File

@ -1,8 +1,10 @@
#[abi = "rust-intrinsic"]
native mod rusti {
fn frame_address() -> *u8;
fn frame_address(f: fn(*u8));
}
fn main() {
assert rusti::frame_address().is_not_null();
rusti::frame_address {|addr|
assert addr.is_not_null();
}
}