diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2014-08-04 11:48:26 -0700 |
|---|---|---|
| committer | Luqman Aden <me@luqman.ca> | 2014-08-11 19:20:10 -0700 |
| commit | 9dac85f92daa094f94f124fd06cfeb5339d48772 (patch) | |
| tree | 45465497869bcf25378b43be0b40469c5a526155 /src | |
| parent | d3028138889d8eb2aaa3dce899d556f8bbf04d13 (diff) | |
| download | rust-9dac85f92daa094f94f124fd06cfeb5339d48772.tar.gz rust-9dac85f92daa094f94f124fd06cfeb5339d48772.zip | |
librustc: Add an intrinsic to retrieve the return pointer of a function.
This is needed for some GC stuff in Servo.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/middle/trans/intrinsic.rs | 6 | ||||
| -rw-r--r-- | src/librustc/middle/typeck/check/mod.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/intrinsic-return-address.rs | 43 |
3 files changed, 51 insertions, 0 deletions
diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs index fb420a4035d..154f2b122ab 100644 --- a/src/librustc/middle/trans/intrinsic.rs +++ b/src/librustc/middle/trans/intrinsic.rs @@ -425,6 +425,12 @@ pub fn trans_intrinsic_call<'a>(mut bcx: &'a Block<'a>, node: ast::NodeId, with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i64", ret_ty, *llargs.get(0), *llargs.get(1)), + (_, "return_address") => { + PointerCast(bcx, + bcx.fcx.llretptr.get().unwrap(), + Type::i8p(bcx.ccx())) + } + // This requires that atomic intrinsics follow a specific naming pattern: // "atomic_<operation>[_<ordering>]", and no ordering means SeqCst (_, name) if name.starts_with("atomic_") => { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 787a4bebc55..aa38ff68f24 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -4986,6 +4986,8 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { (0, vec!(ty::mk_u64(), ty::mk_u64()), ty::mk_tup(tcx, vec!(ty::mk_u64(), ty::mk_bool()))), + "return_address" => (0, vec![], ty::mk_imm_ptr(tcx, ty::mk_u8())), + ref other => { span_err!(tcx.sess, it.span, E0093, "unrecognized intrinsic function: `{}`", *other); diff --git a/src/test/run-pass/intrinsic-return-address.rs b/src/test/run-pass/intrinsic-return-address.rs new file mode 100644 index 00000000000..a28a79d306b --- /dev/null +++ b/src/test/run-pass/intrinsic-return-address.rs @@ -0,0 +1,43 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(intrinsics)]; + +use std::ptr; + +struct Point { + x: f32, + y: f32, + z: f32, +} + +extern "rust-intrinsic" { + fn return_address() -> *const u8; +} + +fn f(result: &mut uint) -> Point { + unsafe { + *result = return_address() as uint; + Point { + x: 1.0, + y: 2.0, + z: 3.0, + } + } + +} + +fn main() { + let mut intrinsic_reported_address = 0; + let pt = f(&mut intrinsic_reported_address); + let actual_address = &pt as *const Point as uint; + assert_eq!(intrinsic_reported_address, actual_address); +} + |
