rustc: Add frame_address intrinsic

This commit is contained in:
Brian Anderson 2012-06-05 18:41:18 -07:00
parent c816eea000
commit 125552fb19
4 changed files with 63 additions and 10 deletions

View File

@ -5301,6 +5301,7 @@ fn declare_intrinsics(llmod: ModuleRef) -> hashmap<str, ValueRef> {
let T_memset64_args: [TypeRef] =
[T_ptr(T_i8()), T_i8(), T_i64(), T_i32(), T_i1()];
let T_trap_args: [TypeRef] = [];
let T_frameaddress_args: [TypeRef] = [T_i32()];
let gcroot =
decl_cdecl_fn(llmod, "llvm.gcroot",
T_fn([T_ptr(T_ptr(T_i8())), T_ptr(T_i8())], T_void()));
@ -5320,6 +5321,9 @@ fn declare_intrinsics(llmod: ModuleRef) -> hashmap<str, ValueRef> {
decl_cdecl_fn(llmod, "llvm.memset.p0i8.i64",
T_fn(T_memset64_args, T_void()));
let trap = decl_cdecl_fn(llmod, "llvm.trap", T_fn(T_trap_args, T_void()));
let frameaddress = decl_cdecl_fn(llmod, "llvm.frameaddress",
T_fn(T_frameaddress_args,
T_ptr(T_i8())));
let intrinsics = str_hash::<ValueRef>();
intrinsics.insert("llvm.gcroot", gcroot);
intrinsics.insert("llvm.gcread", gcread);
@ -5328,6 +5332,7 @@ fn declare_intrinsics(llmod: ModuleRef) -> hashmap<str, ValueRef> {
intrinsics.insert("llvm.memset.p0i8.i32", memset32);
intrinsics.insert("llvm.memset.p0i8.i64", memset64);
intrinsics.insert("llvm.trap", trap);
intrinsics.insert("llvm.frameaddress", frameaddress);
ret intrinsics;
}

View File

@ -755,22 +755,44 @@ fn trans_native_mod(ccx: @crate_ctxt,
}
let mut cc = alt abi {
ast::native_abi_rust_intrinsic { ret; }
ast::native_abi_rust_intrinsic |
ast::native_abi_cdecl { lib::llvm::CCallConv }
ast::native_abi_stdcall { lib::llvm::X86StdcallCallConv }
};
for vec::each(native_mod.items) {|native_item|
alt native_item.node {
ast::native_item_fn(fn_decl, _) {
ast::native_item_fn(fn_decl, typarams) {
let id = native_item.id;
let llwrapfn = get_item_val(ccx, id);
let tys = c_stack_tys(ccx, id);
if attr::attrs_contains_name(native_item.attrs, "rust_stack") {
build_direct_fn(ccx, llwrapfn, native_item, tys, cc);
if abi != ast::native_abi_rust_intrinsic {
let llwrapfn = get_item_val(ccx, id);
let tys = c_stack_tys(ccx, id);
if attr::attrs_contains_name(native_item.attrs, "rust_stack") {
build_direct_fn(ccx, llwrapfn, native_item, tys, cc);
} else {
let llshimfn = build_shim_fn(ccx, native_item, tys, cc);
build_wrap_fn(ccx, tys, llshimfn, llwrapfn);
}
} else {
let llshimfn = build_shim_fn(ccx, native_item, tys, cc);
build_wrap_fn(ccx, tys, llshimfn, llwrapfn);
// Intrinsics with type parameters are emitted by
// monomorphic_fn, but ones without are emitted here
if typarams.is_empty() {
let llwrapfn = get_item_val(ccx, id);
let path = alt ccx.tcx.items.find(id) {
some(ast_map::node_native_item(_, _, pt)) { pt }
_ {
ccx.sess.span_bug(native_item.span,
"can't find intrinsic path")
}
};
let psubsts = {
tys: [],
vtables: none,
bounds: @[]
};
trans_intrinsic(ccx, llwrapfn, native_item,
*path, psubsts, none);
}
}
}
}
@ -783,31 +805,41 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::native_item,
let fcx = new_fn_ctxt_w_id(ccx, path, decl, item.id,
some(substs), some(item.span));
let mut bcx = top_scope_block(fcx, none), lltop = bcx.llbb;
let tp_ty = substs.tys[0], lltp_ty = type_of::type_of(ccx, tp_ty);
alt check item.ident {
"size_of" {
let tp_ty = substs.tys[0];
let lltp_ty = type_of::type_of(ccx, tp_ty);
Store(bcx, C_uint(ccx, shape::llsize_of_real(ccx, lltp_ty)),
fcx.llretptr);
}
"min_align_of" {
let tp_ty = substs.tys[0];
let lltp_ty = type_of::type_of(ccx, tp_ty);
Store(bcx, C_uint(ccx, shape::llalign_of_min(ccx, lltp_ty)),
fcx.llretptr);
}
"pref_align_of" {
let tp_ty = substs.tys[0];
let lltp_ty = type_of::type_of(ccx, tp_ty);
Store(bcx, C_uint(ccx, shape::llalign_of_pref(ccx, lltp_ty)),
fcx.llretptr);
}
"get_tydesc" {
let tp_ty = substs.tys[0];
let td = get_tydesc_simple(ccx, tp_ty);
Store(bcx, PointerCast(bcx, td, T_ptr(T_nil())), fcx.llretptr);
}
"init" {
let tp_ty = substs.tys[0];
let lltp_ty = type_of::type_of(ccx, tp_ty);
if !ty::type_is_nil(tp_ty) {
Store(bcx, C_null(lltp_ty), fcx.llretptr);
}
}
"forget" {}
"reinterpret_cast" {
let tp_ty = substs.tys[0];
let lltp_ty = type_of::type_of(ccx, tp_ty);
let llout_ty = type_of::type_of(ccx, substs.tys[1]);
let tp_sz = shape::llsize_of_real(ccx, lltp_ty),
out_sz = shape::llsize_of_real(ccx, llout_ty);
@ -831,6 +863,7 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::native_item,
Store(bcx, get_param(decl, first_real_arg), fcx.llretptr);
}
"needs_drop" {
let tp_ty = substs.tys[0];
Store(bcx, C_bool(ty::type_needs_drop(ccx.tcx, tp_ty)),
fcx.llretptr);
}
@ -839,6 +872,11 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::native_item,
let visitor = get_param(decl, first_real_arg);
call_tydesc_glue(bcx, visitor, tp_ty, abi::tydesc_field_visit_glue);
}
"frame_address" {
let frameaddress = ccx.intrinsics.get("llvm.frameaddress");
let frameaddress_val = Call(bcx, frameaddress, [C_i32(0i32)]);
Store(bcx, frameaddress_val, fcx.llretptr);
}
}
build_return(bcx);
finish_fn(fcx, lltop);

View File

@ -2317,7 +2317,9 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::native_item) {
let (_, visitor_iface) = ccx.tcx.intrinsic_ifaces.get("ty_visitor");
(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)))
}
other {
tcx.sess.span_err(it.span, "unrecognized intrinsic function: `" +
other + "`");

View File

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