Fix metadata serialization of foreign functions. Properly take the value of foreign functions from other crates to fix #1840.

This commit is contained in:
Josh Matthews 2012-07-07 00:52:31 -04:00 committed by Brian Anderson
parent f3b50ae348
commit a7f6e00944
5 changed files with 45 additions and 6 deletions

View File

@ -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)) }

View File

@ -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' }
}
}

View File

@ -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};

View File

@ -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
}
}

View File

@ -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;
}