about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-06-05 18:41:18 -0700
committerBrian Anderson <banderson@mozilla.com>2012-06-06 23:39:56 -0700
commit125552fb1958df89939feb85ac73b080a32ffcfa (patch)
tree0c7971a04d08299d5438b6c4beded94bc3b2f125 /src/rustc
parentc816eea000f56e250bb251dc1a1d357efd5a0438 (diff)
downloadrust-125552fb1958df89939feb85ac73b080a32ffcfa.tar.gz
rust-125552fb1958df89939feb85ac73b080a32ffcfa.zip
rustc: Add frame_address intrinsic
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/middle/trans/base.rs5
-rw-r--r--src/rustc/middle/trans/native.rs56
-rw-r--r--src/rustc/middle/typeck/check.rs4
3 files changed, 55 insertions, 10 deletions
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index c1d05bf39da..7c57c90a5a4 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -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;
 }
 
diff --git a/src/rustc/middle/trans/native.rs b/src/rustc/middle/trans/native.rs
index 445f300cb02..1f399343f13 100644
--- a/src/rustc/middle/trans/native.rs
+++ b/src/rustc/middle/trans/native.rs
@@ -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);
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index b3f7c5a9388..a6bb333c34e 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -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 + "`");