Skip to content

Commit

Permalink
Fix metadata serialization of foreign functions. Properly take the va…
Browse files Browse the repository at this point in the history
…lue of foreign functions from other crates to fix #1840.
  • Loading branch information
jdm authored and brson committed Jul 9, 2012
1 parent f3b50ae commit a7f6e00
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/rustc/metadata/decoder.rs
Expand Up @@ -288,6 +288,7 @@ fn item_to_def_like(item: ebml::doc, did: ast::def_id, cnum: ast::crate_num)
'u' { dl_def(ast::def_fn(did, ast::unsafe_fn)) }
'f' { dl_def(ast::def_fn(did, ast::impure_fn)) }
'p' { dl_def(ast::def_fn(did, ast::pure_fn)) }
'F' { dl_def(ast::def_fn(did, ast::extern_fn)) }
'y' { dl_def(ast::def_ty(did)) }
't' { dl_def(ast::def_ty(did)) }
'm' { dl_def(ast::def_mod(did)) }
Expand Down
2 changes: 1 addition & 1 deletion src/rustc/metadata/encoder.rs
Expand Up @@ -527,7 +527,7 @@ fn purity_fn_family(p: purity) -> char {
unsafe_fn { 'u' }
pure_fn { 'p' }
impure_fn { 'f' }
extern_fn { 'c' }
extern_fn { 'F' }
}
}

Expand Down
12 changes: 7 additions & 5 deletions src/rustc/middle/trans/base.rs
Expand Up @@ -2392,16 +2392,18 @@ fn lval_static_fn_inner(bcx: block, fn_id: ast::def_id, id: ast::node_id,
ccx, node_id_type(bcx, id))));
}

// FIXME: Need to support extern-ABI functions (#1840)
if fn_id.crate == ast::local_crate {
alt bcx.tcx().def_map.find(id) {
some(ast::def_fn(_, ast::extern_fn)) {
alt ty::get(tpt.ty).struct {
ty::ty_fn(fn_ty) {
alt fn_ty.purity {
ast::extern_fn {
// Extern functions are just opaque pointers
let val = PointerCast(bcx, val, T_ptr(T_i8()));
ret lval_no_env(bcx, val, owned_imm);
}
_ { }
_ { /* fall through */ }
}
}
_ { /* fall through */ }
}

ret {bcx: bcx, val: val, kind: owned, env: null_env};
Expand Down
22 changes: 22 additions & 0 deletions src/test/auxiliary/extern-crosscrate-source.rs
@@ -0,0 +1,22 @@
#[link(name = "externcallback",
vers = "0.1")];

#[crate_type = "lib"];

extern mod rustrt {
fn rust_dbg_call(cb: *u8,
data: libc::uintptr_t) -> libc::uintptr_t;
}

fn fact(n: uint) -> uint {
#debug("n = %?", n);
rustrt::rust_dbg_call(cb, n)
}

extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
if data == 1u {
data
} else {
fact(data - 1u) * data
}
}
14 changes: 14 additions & 0 deletions src/test/run-pass/extern-crosscrate.rs
@@ -0,0 +1,14 @@
//aux-build:extern-crosscrate-source.rs

use externcallback(vers = "0.1");

fn fact(n: uint) -> uint {
#debug("n = %?", n);
externcallback::rustrt::rust_dbg_call(externcallback::cb, n)
}

fn main() {
let result = fact(10u);
#debug("result = %?", result);
assert result == 3628800u;
}

0 comments on commit a7f6e00

Please sign in to comment.